等待并通知实现可运行和扩展线程示例



我正在实现逻辑来理解等待和通知工作,当我使用线程扩展类时,我发现了一些我无法分析的东西,然后等待和通知按预期工作,但是当我实现可运行的接口时,输出会有所不同

public class AdderThread extends Thread {
int total;
@Override
public void run() {
    synchronized (this) {
        for (int i = 0; i < 1000; i++) {
            total += i;
        }
        notify();
    }
}


public class WaitNotify {
public static void main(String[] args) {
    AdderThread addrTh = new AdderThread();
    addrTh.start();
    // -1243309312
    System.out.println("Total without Wait() " + addrTh.total);

}

}

当实现 Runnable 给我正确的答案时,这意味着它正在等待线程完成任务,

但当我使用扩展线程时,它给我的答案为 0,即它不是在等待线程完成任务。

public class WaitNotify {
public static void main(String[] args) {
    AdderThread addrTh = new AdderThread();
    addrTh.start();
    // -1243309312
    System.out.println("Total Before Wait " + addrTh.total);
    synchronized (addrTh) {
        try {
            System.out.println("Waiting for Sum...");
            addrTh.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Total " + addrTh.total);
    }
}

}

你的新线程可以在主线程调用 'wait() 之前调用notify()。" 在这种情况下,wait() 调用将永远等待,因为如果其他线程尚未等待它,notify() 根本不会执行任何操作。

wait()notify() 是旨在以非常特定的方式使用的低级操作:

请参阅 Java wait() 不会被 notify() 唤醒以获取更多信息。


实现Runnable的情况与扩展Thread的情况之间的区别是由于this在第一种情况下引用匿名内部类,而在后一种情况下引用Thread对象。

这很重要,因为线程机制使用 wait() 和 notify() 来实现自己的目的。 因此,如果您的wait()调用来得太晚,无法被代码中的notify()调用唤醒,它仍可能被库代码中的notify()唤醒(例如,当线程终止时)。 当您实现Runnable时,这不会发生,因为库没有理由通知它。

最新更新