Maison  >  Article  >  Java  >  Discutez de la différence essentielle entre notify() et notifyAll() à travers des exemples

Discutez de la différence essentielle entre notify() et notifyAll() à travers des exemples

阿神
阿神original
2017-03-18 10:09:002198parcourir

notify() et notifyAll() sont des méthodes utilisées par l'objet Object pour notifier les threads en attente de l'objet. La plus grande différence entre les deux est la suivante :

notifyAll fait en sorte que tous les threads qui attendaient initialement d'être notifiés sur l'objet quittent l'état d'attente et attendent le verrou sur l'objet. Une fois l'objet déverrouillé, ils attendent. volonté de rivaliser.
notify est beaucoup plus civilisé. Il sélectionne simplement un thread d'état d'attente à notifier et lui fait obtenir le verrou sur l'objet, mais n'alerte pas les autres threads qui attendent également d'être avertis par l'objet lorsque le premier thread se termine. en cours d'exécution Libérez le verrou sur l'objet plus tard.Si l'objet n'utilise pas à nouveau l'instruction notify à ce moment-là, même si l'objet est déjà inactif, les autres threads en attente dans l'état d'attente continueront à être dans l'état d'attente car ils ne l'ont pas fait. ont été notifiés par l'objet jusqu'à ce que l'objet émette une notification ou notifyAll, ils attendent d'être notifiés ou notifyAll, pas le verrou.

Ce qui suit est un bon exemple :

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

    }

}

Articles connexes :

Comparaison détaillée de Java notify et notifyAll

Deux façons de coopérer entre les threads dans la concurrence Java : attendre, notifier, notifierAll et Condition

Utilisation correcte de attendre, notifier et notifierAll

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn