I'm using 3rd party library for doing some work in my application. Unfortunately, some bugs were found in it and they cause very sad result: my app is hanging as worker thread probably infinite looping. I've read some questions about killing the thread in android VM but they are didn't help me because of:
The worst thing is that from some moment of time this worker thread starts to use a lot of memory causing GC to run too often which also is not good for app.
I've found some conditions when bug in library is occurred but i there are may be other bugs which i also want to avoid in my app.
Here is ode snippet that shows the problem:
final MutableObject<Object> calculationResult = new MutableObject<Object>(null);
final MutableObject<EvalError> exception = new MutableObject<EvalError>(null);
final MutableObject<Thread> calculationThread = new MutableObject<Thread>(null);
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
final Thread thread = Thread.currentThread();
try {
Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
calculationThread.setObject(thread);
calculationResult.setObject(interpreter.eval(jsclExpression));
} catch (EvalError evalError) {
exception.setObject(evalError);
} finally {
Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
calculationThread.setObject(null);
latch.countDown();
}
}
}).start();
try {
Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName());
latch.await(4, TimeUnit.SECONDS);
Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName());
final EvalError evalErrorLocal = exception.getObject();
final Object calculationResultLocal = calculationResult.getObject();
final Thread calculationThreadLocal = calculationThread.getObject();
if (calculationThreadLocal != null) {
// todo serso: interrupt doesn't stop the thread but it MUST be killed
calculationThreadLocal.interrupt();
resetInterpreter();
}
if ( evalErrorLocal != null ) {
throw evalErrorLocal;
}
if ( calculationResultLocal == null ) {
tooLongExecutionCache.add(jsclExpression);
throw new ParseException("Too long calculation for: " + jsclExpression);
}
} catch (InterruptedException e) {
throw new ParseException(e);
}
Thread could not be killed in davlik:
I used solution proposed by AVD and just set the priority of thread to lowest possible value and invoke interrupt() method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With