notify()和notifyAll()之间的区别 [英] Difference between notify() and notifyAll()

查看:235
本文介绍了notify()和notifyAll()之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道本网站已经讨论过类似的问题,但考虑到一个具体的例子,我还没有得到进一步的帮助。我可以理解notify()和 notifyAll()在理论上关于线程唤醒的区别,但我无法察觉当使用它们中的任何一个而不是另一个时,它们如何影响程序的功能。因此,我设置以下代码,我想知道使用它们中的每一个有什么影响。我可以从一开始就说它们给出相同的输出(Sum打印3次)。

I know that similar questions have been discussed in this site, but I have not still got further by their aid considering a specific example. I can grasp the difference of notify() and notifyAll() regarding Thread "awakeining" in theory but I cannot perceive how they influence the functionality of program when either of them is used instead of the other. Therefore I set the following code and I would like to know what is the impact of using each one of them. I can say from the start that they give the same output (Sum is printed 3 times).

它们实际上有何不同?有人如何修改程序,以便应用通知或 notifyAll 在其功能中发挥关键作用(给出不同的结果)?

How do they differ virtually? How could someone modify the program, in order for the applying notify or notifyAll to play a crucial role to its functionality (to give different results)?

任务:

class MyWidget implements Runnable {
private List<Integer> list;
private int sum;

public MyWidget(List<Integer> l) {
    list = l;
}

public synchronized int getSum() {
    return sum;
}

@Override
public void run() {
    synchronized (this) {
        int total = 0;
        for (Integer i : list)
            total += i;

        sum = total;

        notifyAll();
    }
}

}

线程:

public class MyClient extends Thread {
MyWidget mw;

public MyClient(MyWidget wid) {
    mw = wid;
}

public void run() {
    synchronized (mw) {
        while (mw.getSum() == 0) {
            try {
                mw.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Sum calculated from Thread "
                + Thread.currentThread().getId() + " : " + mw.getSum());
    }
}

public static void main(String[] args) {
    Integer[] array = { 4, 6, 3, 8, 6 };
    List<Integer> integers = Arrays.asList(array);

    MyWidget wid = new MyWidget(integers);

    Thread widThread = new Thread(wid);
    Thread t1 = new MyClient(wid);
    Thread t2 = new MyClient(wid);
    Thread t3 = new MyClient(wid);

    widThread.start();
    t1.start();
    t2.start();
    t3.start();
}

}

更新:
我明确地写了它。无论是使用notify还是notifyAll,结果都是相同的:
从线程12计算的总和:27
从线程11计算的总和:27
从线程10计算的总和:27

UPDATE: I write it explicitly. The result is the same whether one uses notify or notifyAll: Sum calculated from Thread 12 : 27 Sum calculated from Thread 11 : 27 Sum calculated from Thread 10 : 27

因此我的问题:有什么区别?

Therefore my question: What is the difference?

推荐答案

我发现了怎么回事用我的程序。即使使用 notify(),三个 Thread 也会打印结果,因为它们无法进入等待状态。 widThread 中的计算执行得足够快,以便在等待状态下抢占其他 Thread 的输入,因为它取决于条件 mw.getSum()== 0 (while循环)。 widThread 计算总和,以便剩余的 Thread s不会看到其值为0.
如果删除while循环并且 widThread 的开头位于另一个 Thread s的开头之后,然后通过 notify()只有一个线程打印结果,而其他人则永远等待理论和其他答案表明。

I found what is going on with my program. The three Threads print the result even with the notify(), because they do not manage to enter the waiting state. The calculation in the widThread is performed quickly enough to preempt the entering of the other Threads in the waiting state, since it depends on the condition mw.getSum() == 0 (while loop). The widThread calculates the sum, so that the remaining Threads do not ever "see" its value as 0. If the while loop is removed and the start of widThread comes after the start of the other Threads, then by notify() only one Thread prints the result and the others are waiting forever, as the theory and the other answers indicate.

这篇关于notify()和notifyAll()之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆