Stopping/Destroying a Thread Stopping/Destroying a Thread multithreading multithreading

Stopping/Destroying a Thread


The thread destroy and stop methods are inherently deadlock prone and not safe. Their existence also gives the illusion that there might be some way of halting another thread immediately when something else tells it to.

I understand your thinking, from your point of view their is one main thread, and when this thread hasn't received a response from it's worker thread in a while you'd like to kill it and restart it, without caring what it's up to. But the reason those methods are deprecated is you should care what the thread is up to. A lot.

What if the thread has a lock around a variable you need to use later? What if a thread has a file handle open? In all these cases, and many more, simply stopping the thread at it's current operation would leave things in mess -- quite likely your application would just crash further down the line.

So in order for a thread to be interruptible or cancel-able or stoppable, it has to manage this itself. If a thread or operation provides no way for itself to be interrupted, then you cannot interrupt it - it is assumed to do so would be unsafe.

If you runnable is literally

public void run() {   doSomething();}

then there is no way to interrupt it. One would hope that if doSomething were a long operation that there might be a way to either interact with it incrementally with something like

public void run() {   while (running) {       MyParser.parseNext();   }}

or to be able to pass in a variable by reference which indicates whether the thread is interrupted or not, and hopefully the method would interrupt itself at suitable location.

Remember a blocking operation is blocking. There is no way to get around that, you cannot cancel it part way through.


Alternative answer

Use the following code:

MyThread thread;     // class field

Create and start the thread as you do it right now.

thread = new MyThread();thread.start();

When the service is destroyed, "signal" the thread to quit

public void onDestroy() {    // Stop the thread    thread.abort = true;    thread.interrupt();}

Here is thread implementation

//another class or maybe an inner classclass MyThread extends Thread {    syncronized boolean abort = false;    //ugly, I know    public void run() {       try {           if(!abort) doA();           if(!abort) doB();           if(!abort) doC();           if(!abort) doD();       } catch (InterruptedException ex) {          Log.w("tag", "Interrupted!");       }    }}

You might want to read the following:

I think that you could rely on catching the exception and not check abort but I decided to keep it that way.

UPDATE

I've seen this sample in codeguru:

public class Worker implements Runnable {    private String result;    public run() {        result = blockingMethodCall();    }    public String getResult() {        return result;    }}public class MainProgram {    public void mainMethod() {        ...        Worker worker = new Worker();         Thread thread = new Thread(worker);         thread.start();        // Returns when finished executing, or after maximum TIME_OUT time        thread.join(TIME_OUT);         if (thread.isAlive()) {            // If the thread is still alive, it's still blocking on the methodcall, try stopping it            thread.interrupt();            return null;        } else {            // The thread is finished, get the result            return worker.getResult();         }    }}


Did you check the Java Thread Primitive Deprecation Documentation which is referenced in the Thread API JavaDoc. You will find some hints to handle your problem.