ホームページ  >  記事  >  Java  >  例を通して、notify() とnotifyAll() の本質的な違いについて説明します。

例を通して、notify() とnotifyAll() の本質的な違いについて説明します。

阿神
阿神オリジナル
2017-03-18 10:09:002140ブラウズ

notify()notifyAll() はどちらも、オブジェクトを待機しているスレッドに通知するために Object オブジェクトによって使用されるメソッドです。 2 つの最大の違いは次のとおりです。

notifyAll では、オブジェクトの通知を待っていたすべてのスレッドが待機状態を終了し、オブジェクトのロックが解除されると、スレッドが競合します。
通知は、通知する待機状態のスレッドを選択し、オブジェクトのロックを取得するだけですが、同様にオブジェクトからの通知を待っている他のスレッドを妨げません。最初のスレッドが解放されるときに解放されます。この時点でオブジェクトが再度通知ステートメントを使用しない場合、オブジェクトがすでにアイドル状態であっても、待機状態で待機している他のスレッドはオブジェクトから通知を受けないため、引き続き待機状態になります。オブジェクトは Notice または NoticeAll を発行しますが、ロックではなく、Notify または NotifyAll を待っています。

ここに良い例があります:

import java.util.*;

class Widget...{}
class WidgetMaker extends Thread...{
    List<Widget> finishedWidgets=new ArrayList<Widget>();
    public void run()...{
        try...{
            while(true)...{
                Thread.sleep(5000);//act busy
                Widget w=new Widget();
                //也就是说需要5秒钟才能新产生一个Widget,这决定了一定要用notify而不是notifyAll
                //因为上面两行代码不是同步的,如果用notifyAll则所有线程都企图冲出wait状态
                //第一个线程得到了锁,并取走了Widget(这个过程的时间小于5秒,新的Widget还没有生成)
                //并且解开了锁,然后第二个线程获得锁(因为用了notifyAll其他线程不再等待notify语句
                //,而是等待finishedWidgets上的锁,一旦锁放开了,他们就会竞争运行),运行
                //finishedWidgets.remove(0),但是由于finishedWidgets现在还是空的,
                //于是产生异常
                //***********这就是为什么下面的那一句不能用notifyAll而是要用notify
                                
                synchronized(finishedWidgets)...{
                    finishedWidgets.add(w);
                    finishedWidgets.notify(); //这里只能是notify而不能是notifyAll
                }
            }
        }
        catch(InterruptedException e)...{}
    }
    
    public Widget waitForWidget()...{
        synchronized(finishedWidgets)...{
            if(finishedWidgets.size()==0)...{
                try...{
                    finishedWidgets.wait();
                }
                catch(InterruptedException e)
                ...{}
            }
            return finishedWidgets.remove(0);
        }
    }
}
public class WidgetUser extends Thread...{
    private WidgetMaker maker;
    public WidgetUser(String name,WidgetMaker maker)...{
        super(name);
        this.maker=maker;
    }
    public void run()...{
        Widget w=maker.waitForWidget();
        System.out.println(getName()+"got a widget");
    }
   

    public static void main(String[] args) ...{
        WidgetMaker maker=new WidgetMaker();
        maker.start();
        new WidgetUser("Lenny",maker).start();
        new WidgetUser("Moe",maker).start();
        new WidgetUser("Curly",maker).start();

    }

}

関連記事:

JavaのnotifyとnotifyAllの比較詳細な紹介

Java同時実行におけるスレッド間のコラボレーションの2つの方法: wait、notify、notifyAll、Condition

wait、notify、notifyAll の正しい使い方

以上が例を通して、notify() とnotifyAll() の本質的な違いについて説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。