基于Java多线程notify与notifyall的区别分析
当一个线程进入wait之后,就必须等其他线程notify/notifyall,使用notifyall,可以唤醒
所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。注意,任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码,notifyall只是让处于wait的线程重新拥有锁的争夺权,但是只会有一个获得锁并执行。
那么notify和notifyall在效果上又什么实质区别呢?
主要的效果区别是notify用得不好容易导致死锁,例如下面提到的例子。
代码如下:
public synchronized void put(Object o) {
while (buf.size()==MAX_SIZE) {
wait(); // called if the buffer is full (try/catch removed for brevity)
}
buf.add(o);
notify(); // called in case there are any getters or putters waiting
}
public synchronized Object get() {
// Y: this is where C2 tries to acquire the lock (i.e. at the beginning of the method)
while (buf.size()==0) {
wait(); // called if the buffer is empty (try/catch removed for brevity)
// X: this is where C1 tries to re-acquire the lock (see below)
}
Object o = buf.remove(0);
notify(); // called if there are any getters or putters waiting
return o;
}
所以除非你非常确定notify没有问题,大部分情况还是是用notifyall。
更多详细的介绍可以参看:
http://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again
相关推荐
-
java多线程之wait(),notify(),notifyAll()的详解分析
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对象都有wait(),notify(),notifyAll()的功能.因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了. wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或被其他线程中断.wait只能由持有对像锁的线程来调用. notify唤醒在此对象监视器上等待的单个线程.如果所有线程都在此对象上等
-
java notify和notifyAll的对比
java notify和notifyAll 首先从名字可以了解,notify是通知一个线程获取锁,notifyAll是通知所有相关的线程去竞争锁. notify不能保证获得锁的线程,真正需要锁,并且可能产生死锁. 举例1: 所有人(消费者线程)准备吃饭,食堂没有开放(没有释放锁)打饭窗口(锁),所有人等待(WAITING). 食堂开饭打饭窗口(释放锁),并广播消息"开饭了"(notifyAll),所有人竞争排队,并等待吃饭(BLOCKED).每一个人依次在打饭窗口(获得锁)打饭(RU
-
Java的wait(), notify()和notifyAll()使用心得
wait(),notify()和notifyAll()都是java.lang.Object的方法:wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.notify(): Wakes up a single thread that is waiting on this object's
-
Java中的notyfy()和notifyAll()的本质区别
wait()方法表示,放弃当前对资源的占有权,等啊等啊,一直等到有人通知我,我才会运行后面的代码. notify()方法表示,当前的线程已经放弃对资源的占有, 通知等待的线程来获得对资源的占有权,但是只有一个线程能够从wait状态中恢复, 然后继续运行wait()后面的语句: notifyAll()方法表示,当前的线程已经放弃对资源的占有, 通知所有的等待线程从wait()方法后的语句开始运行. 读出什么区别没有? 上例子,先是一个nofiyAll()的例子: Java代码 package co
-
Java notify和notifyAll的区别和相同
经常在往上逛,关于在java中notify和notifyAll,经常有人有以下的说法: notify只会通知一个在等待的对象,而notifyAll会通知所有在等待的对象,并且所有对象都会继续运行 并且,好像都有例子可以证明.上面的说法,可以说对,也可以说不对.究其原因,在于其中有一点很关键,官方的说法如下所示: wait,notify,notifyAll: 此方法只应由作为此对象监视器的所有者的线程来调用.通过以下三种方法之一,线程可以成为此对象监视器的所有者 : 通过执行此对象的同步实例方法.
-
基于Java多线程notify与notifyall的区别分析
当一个线程进入wait之后,就必须等其他线程notify/notifyall,使用notifyall,可以唤醒所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个.注意,任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码,notifyall只是让处于wait的线程重新拥有锁的争夺权,但是只会有一个获得锁并执行. 那么notify和notifyall在效果上又什么实质区别呢?主要的效果区别是notify用得不好容易导致死锁,
-
Java中notify和notifyAll的区别及何时使用
提几个问题,从问题中去了解去学习: 他们之间有啥区别? 如果我使用notify(),将通知哪个线程? 我怎么知道有多少线程在等待,所以我可以使用notifyAll()? 如何调用notify()? 什么是这些线程等待被通知等? 我给点建议:建议使用jdk8里的lock包 java.util.concurrent.locks下的Condition 他可以支持唤醒指定的线程. 他只是一个接口 具体实现类是在AbstractQueuedSynchronizer 也就是AQS框架里的 你可以自己继承他
-
Java中notify()和notifyAll()的使用区别
notify() 和 notifyAll() 有什么区别? 先解释两个概念. 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁. 锁池:只有获取了对象的锁,线程才能执行对象的 synchronized 代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待 然后再来说notify和notifyAll的区别 如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程
-
java 多线程Thread与runnable的区别
java 多线程Thread与runnable的区别 java中实现多线程的方法有两种:继承Thread类和实现runnable接口 1,继承Thread类,重写父类run()方法 public class thread1 extends Thread { public void run() { for (int i = 0; i < 10000; i++) { System.out.println("我是线程"+this.getId()); } } public static
-
基于Java中throw和throws的区别(详解)
系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 用户程序自定义的异常和应用程序特定的异常,必须借助于 throws 和 throw 语句来定义抛出异常. throw是语句抛出一个异常. 语法:throw (异常对象); throw e; throws是方法可能抛出异常的声明.(用在声明方法时,表示该方法可能要抛出异常) 语法:[(修饰符)](返回
-
Java 多线程Synchronized和Lock的区别
引言 在多线程中,为了使线程安全,我们经常会使用synchronized和Lock进行代码同步和加锁,但是具体两者有什么区别,什么场景下适合用什么可能还不大清楚,主要的区别大致如下: 区别 1.synchronized是java关键字,而Lock是java中的一个接口 2.synchronized会自动释放锁,而Lock必须手动释放锁 3.synchronized是不可中断的,Lock可以中断也可以不中断 4.通过Lock可以知道线程有没有拿到锁,而synchronized不能 5.synchr
-
Java拦截器和过滤器的区别分析
一.过滤器(filter) 过滤器处于客户端与Web资源(Servlet.JSP.HTML)之间,客户端与Web资源之间的请求和响应都要通过过滤器进行过滤.举例:在过滤器中定义了禁止访问192.10.10.1这个地址,那么当客户端发出访问192.10.10.1的请求时,经过过滤器后,客户端得到的响应是出现该IP禁止访问的提示.在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑
-
基于java构造方法Vector删除元素源码分析
目录 前言 remove(int)方法分析 remove(Object)方法分析 removeElement(Object)方法分析 removeElementAt(int)方法分析 removeIf()方法分析 removeAllElement()方法分析 removeAll(Collection)方法分析 父类中的removeAll(Collection)方法分析 retainAll(Collection)方法分析 总结 (注意:本文基于JDK1.8) 前言 包括迭代器中的remove()方
-
基于java构造方法Vector查找元素源码分析
目录 前言 get(int)方法分析 contains(Object)方法分析 containsAll()方法分析 indexOf(Object)方法分析 indexOf(Object,index)方法分析 lastIndexOf(Object)方法分析 elementAt(int)方法分析 firstElement()方法分析 lastElement()方法分析 elementData(int)方法分析 总结 (注意:本文基于JDK1.8) 前言 元素在存储到内存中,当我们需要使用在内存中存储
随机推荐
- Python中的id()函数指的什么
- js 弹出框只弹一次(二次修改之后的)
- 使用开源工具制作网页验证码的方法
- js实现iGoogleDivDrag模块拖动层拖动特效的方法
- js HTML5 canvas绘制图片的方法
- 配置支持SSI
- PHP实现根据银行卡号判断银行
- PHP用正则匹配form表单中所有元素的类型和属性值实例代码
- PHP中ini_set与ini_get用法实例
- Python函数中定义参数的四种方式
- C语言 二叉树的链式存储实例
- PHP中配置IIS7实现基本身份验证的方法
- Mysql数据库的一些命令
- CentOS 7.x下的LEMP环境搭建详细教程
- IIS下自定义404页面返回200状态码的严重性及解决方法
- jQuery EasyUI API 中文文档 DateTimeBox日期时间框
- jQuery的extend方法【三种】
- 使用button标签,实现三态图片按钮
- C#实现异步编程的方法
- php 结果集的分页实现代码