线程在调用 stop() 方法时不会停止

Kic*_*ick 2 java multithreading

我已经创建了 java Thread 的示例程序,其中我使用 stop() 方法来停止使用以下程序的线程

public class App extends Thread
{
    Thread th;

    App(String threadName)
    {
        th = new Thread(threadName);
    }

    public synchronized void run() // Remove synchronized
    {
        for (int i = 0; i < 5; i++) {
            System.out.println(th.getName()+" "+i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }
        }
    }

    public static void main( String[] args ) 
    {
       App thread_1 = new App("Thread-1");
       thread_1.start();
       thread_1.setPriority(MAX_PRIORITY); //Comment this
       thread_1.stop();
       App thread_2 = new App("Thread-2");
       thread_2.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面程序的输出是:

Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
Run Code Online (Sandbox Code Playgroud)

即 thread_1 没有停止。当我删除代码中的同步或优先级时,线程立即停止并且输出将是

Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么它会这样工作。

Sol*_*low 5

Thread 类的大多数公共方法都是在 Thread 实例本身上同步的。 http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/5672a2be515a/src/share/classes/java/lang/Thread.java

您的 run() 方法在 Thread 实例上同步。stop()方法调用了stop(Throwable),在Thread实例上也是同步的,它的签名是:

@Deprecated
public final synchronized void stop(Throwable obj) {
Run Code Online (Sandbox Code Playgroud)

thread_1.stop()当线程本身仍在您的synchronized run()方法中运行时,同步会阻止主线程进入。


这是一个为什么总是使用私有对象进行同步是明智的例子。例如,这样做...

class Foobar {
    private final Object lock = new Object();

    public void do_something() {
        synchronized(lock) {
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而不是这样做...

class Foobar {
    public synchronized void do_something() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个版本更加冗长(欢迎使用 Java!),但它阻止 Foobar 类的用户以干扰其自身作为同步对象的方式使用它作为同步对象。