用实例揭示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();
    }
}

同步机制中notify()与wait()--实现A,B,C循环打印

关于同步与异步机制,听过很多通俗的解释。 日常生活中其实也有很多这样的例子,比如吃饭的时候 同步:就是你通知我去吃饭,我听到了就和你一起去,如果我没有回应,你就会一直喊,直到我有反映了为止。 异...

Dubbo是什么

1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实...
  • azhegps
  • azhegps
  • 2016年09月19日 15:07
  • 113

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

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

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

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

关键字Ref和Out本质区别实例分析

学过C/C++的人,对C#的关键字Ref和Out应该都很好理解。它们都提供了一种可以在被调用函数内修改传递的参数的值的方法。因为这一功能很类似C/C++的指针。对于没学过C/C++的,也应该可以明白这...

struts1与struts2本质区别

  • 2010年12月01日 09:59
  • 25KB
  • 下载

转载--最简实例说明wait、notify、notifyAll的使用方法

/** *  转载 *  原作者longdick    http://longdick.iteye.com  修改zdyang 代码内红色部分修改 * */   wait()、notif...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用实例揭示notify()和notifyAll()的本质区别
举报原因:
原因补充:

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