Heim  >  Artikel  >  Java  >  Besprechen Sie den wesentlichen Unterschied zwischen notify() und notifyAll() anhand von Beispielen

Besprechen Sie den wesentlichen Unterschied zwischen notify() und notifyAll() anhand von Beispielen

阿神
阿神Original
2017-03-18 10:09:002140Durchsuche

notify() und notifyAll() sind Methoden, die vom Object-Objekt verwendet werden, um Threads zu benachrichtigen, die auf das Objekt warten. Der größte Unterschied zwischen den beiden ist:

notifyAll bewirkt, dass alle Threads, die ursprünglich auf eine Benachrichtigung für das Objekt warteten, den Wartezustand verlassen und auf die Sperre für das Objekt warten Wille konkurrieren.
notify ist viel zivilisierter. Es wählt lediglich einen Wartestatus-Thread zur Benachrichtigung aus und veranlasst ihn, die Sperre für das Objekt zu erhalten, benachrichtigt jedoch nicht andere Threads, die ebenfalls auf die Benachrichtigung durch das Objekt warten Wenn das Objekt nach dem Aufheben der Sperre für das Objekt die Benachrichtigungsanweisung nicht erneut verwendet, befinden sich andere Threads, die im Wartezustand warten, weiterhin im Wartezustand, auch wenn das Objekt bereits inaktiv ist, da sie nicht benachrichtigt wurden das Objekt, bis das Objekt eine Benachrichtigung ausgibt, oder notifyAll, sie warten auf die Benachrichtigung oder notifyAll, nicht auf die Sperre.

Das Folgende ist ein gutes Beispiel:

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();

    }

}

Verwandte Artikel:

Detaillierter Vergleich von Java Notify und NotifyAll

Zwei Möglichkeiten der Zusammenarbeit zwischen Threads in der Java-Parallelität: Warten, Benachrichtigen, NotifyAll und Bedingung

Korrekte Verwendung von Warten, Benachrichtigen und NotifyAll

Das obige ist der detaillierte Inhalt vonBesprechen Sie den wesentlichen Unterschied zwischen notify() und notifyAll() anhand von Beispielen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn