用实例揭示notify()和notifyAll()的本质区别

转载 2012年03月26日 14:16:23
用实例揭示notify()和notifyAll()的本质区别
作者:袖之欢 发表于 12:47 Java 评论
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于:

notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,它们就会去竞争。notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁

import java.util.*;
class Widget{}
class WidgetMaker extends Thread{
    List finishedWidgets=new ArrayList();
    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();
    }
}

最简实例说明WAIT、NOTIFY、NOTIFYALL的使用方法

wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。 这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可...
  • jackmtlee
  • jackmtlee
  • 2016年04月06日 21:14
  • 609

Java—用实例揭示notify()和notifyAll()的本质区别

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于: notifyAll使所有原来在该对象上等待被notify的线程统统退出wai...
  • weiguishan
  • weiguishan
  • 2015年02月22日 12:58
  • 2611

用实例揭示notify()和notifyAll()的本质区别

http://www.cnblogs.com/armyao/archive/2010/12/27/1917989.html
  • glgl2424
  • glgl2424
  • 2014年04月29日 07:58
  • 349

转载:用实例揭示notify()和notifyAll()的本质区别 收藏

转载:用实例揭示notify()和notifyAll()的本质区别 收藏notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。 两者的最大区别在于: not...
  • u010429424
  • u010429424
  • 2017年09月25日 11:18
  • 119

notify和notifyAll的一段儿代码分析

当你Google”notify()和notifyAll()的区别”时,会有大片的结果弹出来,(这里先把jdk的javadoc文档那一段撇开不说),所有这些搜索结果归结为等待的线程被唤醒的数量:noti...
  • tayanxunhua
  • tayanxunhua
  • 2014年03月11日 10:48
  • 3749

我见过的关于notify()和notifyAll()区别的最简洁的代码

转自:  http://wangacidlemon.iteye.com/blog/398623 wait()方法表示,放弃当前对资源的占有权,等啊等啊,一直等到有人通知我,我才会运行后面的代...
  • cloudeagle_bupt
  • cloudeagle_bupt
  • 2014年03月17日 11:33
  • 5980

java notify()和notifyall()的区别&wait()方法的使用

剖析了notify()和notifyAll()方法的区别。
  • leixingbang1989
  • leixingbang1989
  • 2015年12月30日 15:22
  • 844

java中notify()和notifyall的区别

notify(); 调用后虚拟机可选择任何一个调用了guard.wait()的线程投入运行,选择顺序不由代码控制,由虚拟机实现。 如果是notifyAll(),则唤醒所有等待的线程运行。...
  • qq_29678299
  • qq_29678299
  • 2016年05月24日 15:42
  • 500

Java并发编程系列之八:wait()、notify()和notifyAll()

代码一个线程修改一个对象的值,而另一个线程则感知到了变化,然后进行相应的操作,这就是wait()、notify()和notifyAll()方法的本质。具体体现到方法上则是这样的:一个线程A调用了对象o...
  • u011116672
  • u011116672
  • 2016年04月02日 18:47
  • 4161

android notify() notifyAll()的区别

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。 void notify(): 唤醒一个正在等待该对象的线程。 void notifyAll()...
  • u011467537
  • u011467537
  • 2015年01月26日 16:21
  • 3150
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用实例揭示notify()和notifyAll()的本质区别
举报原因:
原因补充:

(最多只允许输入30个字)