最近在多线程编程中用到了wait(),随之即面临notify与notifyAll的选择、本人代码中使用两者皆可,查看两者的定义后、发现两者的选择还是很讲究的。
所有处于wait状态的线程,需要使用notify或者notifyAll才能被唤醒、重新被唤醒进入锁的争夺队列。notify即随机唤醒等待中的一条线程;notifyAll即唤醒全部处于等待中的线程。
两者的使用上都存在缺陷,使用notify时、容易导致死锁,而使用notifyAll时容易导致资源竞争使用的异常。所以两者的使用得根据实际情况选择、并没有说普遍的说法。下面分别提供两者使用出错的例子供参考:
使用notify出现死锁:
public class NotifyTest { public static void main(String[] args) { final OutTurn ot = new OutTurn(); for(int i=0; i<30; i++) { new Thread(new Runnable() { public void run() { ot.isSub(); } }).start(); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0; i<30; i++) { new Thread(new Runnable() { public void run() { ot.isNotSub(); } }).start(); } System.out.println("Thread cread complate..."); } }
public class OutTurn { private boolean isSub = true; private int count = 0; private int threadCount = 0; public synchronized void isSub() { System.out.println(threadCount++); try { while(!isSub) { System.out.println(Thread.currentThread().getName() + "- sub --- wait --" + count); this.wait(); } System.out.println(Thread.currentThread().getName() + "- sub --- " + count); isSub = false; this.notify();\\采用notifyAll即不会死锁 } catch (Exception e) { e.printStackTrace(); } count++; } public synchronized void isNotSub() { System.out.println(threadCount++); try { while(isSub) { System.out.println(Thread.currentThread().getName() + "- Not --- wait ---" + count); this.wait(); } System.out.println(Thread.currentThread().getName() + "- Not --- " + count); isSub = true; this.notify(); } catch (Exception e) { e.printStackTrace(); } count++; } }
使用notifyAll出现异常:
package notify; import java.util.ArrayList; import java.util.List; public class IntegerMaker implements Runnable { List<Integer> container = new ArrayList<Integer>(); Integer i = 1; @Override public void run() { try { while(true) { Thread.sleep(5000); Integer a = i++; synchronized(container) { container.add(a); container.notify();//notifyAll将出现异常 } } } catch (InterruptedException e) { e.printStackTrace(); } } public Integer waitFor() { synchronized(container) { System.out.println("size"); try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } if(container.size() == 0) { try { container.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("size: " + container.size()); return container.remove(0); } } }
package notify; public class IntegerUser implements Runnable { private IntegerMaker maker; private String name; public IntegerUser(IntegerMaker maker, String name) { this.maker = maker; this.name = name; } public void run() { Integer a = maker.waitFor(); System.out.println(this.name + ":get:" + a); } public static void main(String[] args) { IntegerMaker temp = new IntegerMaker(); Thread maker = new Thread(temp); maker.start(); new Thread(new IntegerUser(temp, "xiaoge1"), "xiaoge1").start(); new Thread(new IntegerUser(temp, "xiaoge2"), "xiaoge2").start(); new Thread(new IntegerUser(temp, "xiaoge3"), "xiaoge3").start(); } }
因此两者的选择必须根据实际情况做具体的分析、然后决定应该唤醒一个还是全部。
相关推荐
Java 同步方式 wait和notify/notifyall
本文主要介绍Java notify和notifyAll的知识,这里整理详细的资料来说明notify 和NotifAll的区别,有需要的小伙伴可以参考下
本篇文章对Java中多线程notify与notifyall的区别进行了详细的分析介绍。需要的朋友参考下
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notify 和 notifyAll 来实现...
1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程顺序打印问题2.1.1 题目2.1.2 题目分析2.1.3 我的答案2.2 生产者消费者问题2.2.1 题目2.2.2 题目分析2.2.3 我的答案 源码...
主要介绍了 java notify和notifyAll的对比的相关资料,需要的朋友可以参考下
源码—Java多线程5—死锁和wait notify notifyAll
主要介绍了Java多线程中wait、notify、notifyAll使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
一个简单的线程同步机制,也能实例了解wait notify的使用,notify与notifyAll的区别
wait()、notify()和notifyAll()方法2---马克-to-win java视频
主要介绍了Java 中Object的wait() notify() notifyAll()方法使用的相关资料,需要的朋友可以参考下
wait()、notify()和notifyAll()方法1---马克-to-win java视频
Java多线程同步(wait()notify()notifyAll())[文].pdf
sleep()与wait()的区别 1.这两个方法来自不同的类,sleep是Thread类的方法,而wait是Object类的方法; 2.执行sleep方法后不会释放锁,而执行wait方法后会释放锁; 3.wait,notify和notifyAll只能在同步方法或同步...
主要介绍了Java多线程基础 线程的等待与唤醒,需要的朋友可以参考下
本篇文章是对java的 wait(),notify(),notifyAll()进行了详细的分析介绍,需要的朋友参考下
绍java多线程之wait(),notify(),notifyAll()
本篇文章是对java多线程 wait(),notify(),notifyAll()进行了详细的分析介绍,需要的朋友参考下
4.线程间通信:lock、condition、wait、notify、notifyAll 5.Lock-free:atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList 6.关于锁的经验介绍 7.并发流程控制手段:CountDownLatch、Barrier 8.定时器:...
很多朋友对java中的notyfy()和notifyAll()的本质区别不了解,今天小编抽空给大家整理一篇教程关于Java中的notyfy()和notifyAll()的本质区别,需要的朋友参考下吧