您的位置:首页 > 移动开发 > Objective-C

Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理

2012-03-03 19:52 483 查看


转载于© 2011 ZeroUp.org


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。


相关代码

obj.wait()内部实现(伪代码):

obj.notify()/notifyAll()内部实现(伪代码):

注意:该代码中之所以用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
相关文章推荐