开发者

Thread stop and synchronization

I'm reading a book which says not to use such a code:

private volatile Thread myThread;

....

myThread.stop();

Instead one should use:

if (myThread != null ) {

 Thread dummy = myThread;

 myThread = null;

 dummy.interrupt();


}

Unfo开发者_如何学Gortunately the subject is not elaborated any further... Could someone explain me this?


stop() is deprecated. Never never and never use stop(). You can use java concurrency instead.

From Javadoc :

This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.

Have a look at Java Concurrency in Practice chapter 7 (Cancellation and Shutdown)


You can find a great answer on why not to use the stop() method here. Instead of using this method you can hold a boolean variable and loop infinitely using this variable:

public class MyRunnable extends Runnable {
    public volatile boolean keepRunning = true;
    public void run() {
        while (keepRunning) {
            ... // do what you have to do
        }
    }
}

Once you decide to finish, you just have to set the keepRunning variable to false. Your thread will then: - finish the remaining steps - terminate

Like that you finish your work in a controlled manner and don't use the unsafe stop() method.


Everyone has given great information on why not to call Thread.stop().

Sergey's comment fixed the incorrect information I gave about interrupt() handling. I prefer to use a signal flag, like in lewap's answer. Like Sergey's said, interrupt() is for the purpose of waking up a thread that's in a blocked operation. If your thread doesn't call any blocking operations, then interrupt() won't actually terminate the thread. Your thread though can call isInterrupted() to see if interrupt has been called (a signal flag, basically).

Going back to your book's example, I don't like it.

if (myThread != null ) {

    Thread dummy = myThread;

    myThread = null;

    dummy.interrupt();

}

There's no good reason to copy to a dummy variable in this example. You are right to be confused.

The book authors might be thinking about trying to prevent other threads from simultaneously attempting to interrupt the same thread, but that interruption code is not thread safe (the "check if null and set to null" operation is not atomic), so writing the dummy assignment is muddying the waters without adding actual thread safety.


Thread.stop() is deprecated. Don't use it. Why? Read Java Thread Primitive Deprecation


Thread.stop is deprecated and should not be used (more info here).

The example code appears to nullify the reference to "myThread" and then signal for it to interrupt. Assuming "myThread" was the only reference to your thread and the code running in the thread is handling interrupt requests properly (and not ignoring them), the thread would end and be eligible for garbage collection when the "if (myThread != null)" code block completes.


Despite the fact that Thread.stop is deprecated. It is also useful to know that with Thread.stop you can circumvent copmiler checked exception control. For example,

public void doSomething(){
    Thread.currentThread().stop(new IOException());
}

That will throw an IOException. An IOException is a checked checked exception and the compiler normally will force the client to catch or let the method throw it. Here doSomething throws an unchecked IOException


In addition to what @Paweloque has suggested (which is a perfect way), there is another alternative to using stop() suggested here

The Wrong Way:

Suppose your applet contains the following start, stop and run methods:

private Thread blinker;

public void start() {
    blinker = new Thread(this);
    blinker.start();
}

public void stop() {
    blinker.stop();  // UNSAFE!
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (true) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

The Correct Way

You can avoid the use of Thread.stop by replacing the applet's stop and run methods with: private volatile Thread blinker;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜