码迷,mamicode.com
首页 > 编程语言 > 详细

Java notify()和notifyAll()同步唤醒上的区别

时间:2015-05-13 12:24:27      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法

  • void notify(): 唤醒一个正在等待该对象的线程。
  • void notifyAll(): 唤醒所有正在等待该对象的线程。

两者的最大区别在于:

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

 

多个线程拥有同一个同步对象时,用notifyAll会造成异常的实例

import java.util.ArrayList;
import java.util.List;

class Widget{}
class WidgetMaker extends Thread{
    List finishedWidgets = new ArrayList();
    public void run(){
         try{
             while(true){
                // 每5s产生对象加入List
                 Thread.sleep(5000);
                 Widget w = new Widget();
                 Widget i = new Widget();
                 Widget d = new Widget();
                 synchronized (finishedWidgets) {
                    finishedWidgets.add(w);
                    finishedWidgets.add(i);
                    finishedWidgets.add(d);
                    // 向List加入3个元素后通知wait对象唤醒
                    // 如果此处使用notifyAll(),第一个线程得到了锁,而其他线程也从wait状态被唤醒执行remove命令,部分List会出现空元素remove出现异常,notify则只选择当前wait状态线程进行唤醒,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们
                    finishedWidgets.notify();
                }
             }
         }catch(InterruptedException e) {}
         }
    // 如果List中有就一直返回,直到List为空时wait
    public Widget waitForWiget() {
        synchronized (finishedWidgets) {
            if (finishedWidgets.size() == 0) {
                try {
                    finishedWidgets.wait();
                } catch (InterruptedException e) {
                }
            }
            return (Widget) 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.waitForWiget();
        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()同步唤醒上的区别

标签:

原文地址:http://www.cnblogs.com/updateofsimon/p/4499720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!