Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
来源:互联网 发布:淘宝投诉号码 编辑:程序博客网 时间:2024/05/22 07:55
http://www.zeroup.org/javas-synchronized-object-wait-object-notify-notifyall-works.html
synchronized与互斥锁mutex
synchronized用来锁定某个对象,体现的是标准的互斥锁mutex的机制,synchronized代码块的开始即是lock该mutex,代码块的结束即是unlock。
Object.wait()与条件变量
Object.wait()在使用时通常要判断是否满足某个条件,不满足某个外部条件cond时调用wait(),来让线程阻塞同时释放被synchronized锁定的mutex;从这个过程看来Object.wait()实际上是起到条件变量的作用,wait()内部实际上先将synchronized锁定的锁释放,之后将当前线程阻塞在某个内置的条件condition上(注意:此condition为内置的,与外部判断的条件cond并非同一个,外部的cond需要程序员根据程序逻辑来判断改变,而这个condition只能被Object.notify()/notifyAll()改变),直到内置条件condition被Object.notify()/notifyAll()修改时才会重新锁定该mutex,继续执行wait()后的代码。
Object.notify()/notifyAll()与条件变量
Object.notify()/notifyAll()实际上只起到一个sinal内置条件变量的作用,调用Object.notify()/notifyAll()之后,这个时候其他处于wait()中的线程所等待的内置条件变量已经满足,但是由于wait()中仍然需要lock mutex,而在Object.notify()/notifyAll()中没有把mutex释放掉,故阻塞在wait()处的线程继续等待,但等待的条件不再是内置条件变量而是锁mutex;直到synchronized代码块结束时,由于会自动释放被synchronized锁定的mutex,故此时所有在wait()中等待mutex的线程开始竞争mutex,得到该mutex的会继续执行,否则继续等待mutex。
相关代码
synchronized
(obj) {
// 此处相当于mutex=obj,lock(mutex)
while
(!cond) {
// 判断外部条件cond,不满足时让线程wait();
obj.wait();
}
// .....执行满足条件cond时的逻辑过程
obj.notifyAll();
// 更改内置条件condition
}
// 此处相当于mutex=obj,unlock(mutex)
obj.wait()内部实现(伪代码):
wait() {
unlock(mutex);
//解锁mutex
wait_condition(condition);
//等待内置条件变量condition
lock(mutex);
//竞争锁
}
obj.notify()/notifyAll()内部实现(伪代码):
obj.notify()/notifyAll(){
condition=
true
;
//只起到把内置条件变量置为true的作用
}
注意:该代码中之所以用while循环判断该外部条件cond,是因为,第一次Object.notify()/notifyAll()被调用之后,所有线程所等待的内部条件condition都已经满足。此时所有线程竞争mutex,而mutex只会被其中一个线程获得,其余线程继续等待在mutex上。当获得mutex的那个线程执行结束时,所有线程又会竞争mutex,此时,某个线程因为获得了mutex而继续执行。 但这个过程中该线程并没有判断外部条件cond是否成立。 也许在第一次获得mutex的线程中已经将外部条件cond改变为false,而当前获得mutex的线程没有判断cond是否为true而直接执行了后续的代码,相当于通过漏洞执行了后续的代码,必然导致程序逻辑的错误。故,必须用while判断外部条件。同时,由此得出,wait和notify所等待和改变的内置条件变量condition一定在obj对象中,只有这样所有被锁定在obj上的线程才能共享该condition。故可以做这样的推断:
被synchronized锁定的mutex为mutex =obj.mutex;
被wait和notify共享的内置条件变量condition = obj.condition;
总结
在使用synchronized、Object.wait()、Object.notify()/notifyAll()实现线程同步时,用到了两种机制:线程互斥锁mutex和条件变量condition。
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()的使用
- Java Object对象中的wait,notify,notifyAll通俗理解
- Object中的wait,notify,notifyAll基本使用
- java Object 类中 notify() ,notifyAll() ,wait()
- Object的notify,wait,notifyAll
- Object.wait notify notifyAll native
- java、synchronized、wait()、notify()、notifyAll()
- wait()、notify()和notifyAll()是 Object类 中的方法
- wait()、notify()和notifyAll()是 Object类 中的方法
- java Object 对象的的wait()、notify()、notifyAll()介绍
- 多线程开发之Object.wait() notify() notifyall()
- Object类wait,notify,notifyAll的使用
- Object的wait、notify、notifyall方法解析
- 关于java中的synchronized、wait以及notify和notifyAll
- java访问xml文件
- 黑马学习---------------反射(执行其他类的main方法)
- java jdbc数据库连接
- size_t
- iphone开发点滴
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
- java自定义按钮外观
- java访问资源文件
- Contacts应用移植
- java日期处理bean
- PHP访问MySQL数据库
- 想了一回儿解决了问题
- eclipse SDK开发嵌入式linux应用程序——C/C++开发环境安装与配置
- Android下打开/关闭wifi 及 状态(5个)的监视