首页 > Java > java教程 > 正文

通过实例讨论notify()和notifyAll()的本质区别

阿神
发布: 2017-03-18 10:09:00
原创
2202 人浏览过

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<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并发之线程间协作的两种方式:wait、notify、notifyAll和Condition

wait, notify 和 notifyAll的正确用法

以上是通过实例讨论notify()和notifyAll()的本质区别的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!