通知是否在线程完成时发出信号?为什么此代码示例有效?

2022-09-03 13:55:06

我正在寻找一些谜题的线程,我不明白为什么以下一致打印:999999

class Job extends Thread {  
    private Integer number = 0;  
    public void run() {  
        for (int i = 1; i < 1000000; i++) {  
            number++;  
        }  
    }  
    public Integer getNumber() {  
        return number;  
    }  
}  
public class Test {  
    public static void main(String[] args)   
    throws InterruptedException {  
        Job thread = new Job();  
        thread.start(); 
        synchronized (thread) {  
            thread.wait();  
        }  
        System.out.println(thread.getNumber());  
    }  
}   

同一个锁上没有(并且似乎忽略了虚假唤醒)。
如果线程完成,通知是否发出信号或其他内容?
为什么打印结果而不被“卡住”等待?notifymain


答案 1

In the Javadoc for Java 7 Thread.join(long)

此实现使用 this.wait 调用的循环,条件是 this.isAlive。当线程终止 this.notifyAll 方法时,将调用该方法。建议应用程序不要在线程实例上使用等待、通知或通知全部。

以这种方式直接使用线程被认为是不切实际的。注意:wait() 可能由于多种原因而结束,可能是虚假的。


基于与@Voo的评论相关的益智游戏。关键是你不应该玩线程的内部行为,因为这更有可能导致混淆。

public static String getName() {
    return "MyProgram";
}
public static void main(String... args) {
    new Thread() {
       public void run() {
           System.out.println("My program is " + getName());
        }
    }.start();
}

此程序打印什么?


答案 2

为了澄清,我已将您的代码修改为:

Job thread = new Job();
thread.start();
final Object lock = new Object();
synchronized (lock) { lock.wait(); }
System.out.println(thread.getNumber());

现在它阻止了。这是对@Nitram在回答中解释的第一手证据。如果您愿意查看实现代码,那么很明显为什么这是观察到的行为。Thread


推荐