用ReentrantLock模拟酒会的热闹情景
用ReentrantLock模拟宴会的热闹情景?用ReentrantLock模拟宴会的热闹情景博客分类:?并发编程threadBlog???
用ReentrantLock模拟宴会的热闹情景
?
用ReentrantLock模拟宴会的热闹情景博客分类:?并发编程threadBlog??? ??? ??? ??? + Thread.currentThread().getName() + ":\t" +msg );
??? }
}
好了, 开始宴会吧.
02:42:24 Tityz:??????? hah, I got the scoop
02:42:25 Tityz:????????? someone rob my scoop, 55~~~?
02:42:25 Michael:??? Some one call me for better food ^^?
02:42:25 Yutting:???? hah, I got the scoop
02:42:25 Michael:??? I will wait for a while to dip, see if any other better...
02:42:25 Tityz:????????? I will wait for a while to dip, see if any other better...
02:42:30 Yutting:???? I got delicious food?
02:42:30 Tityz:????????? hah, I got the scoop
02:42:35 Tityz:????????? I got delicious food?
02:42:35 Michael:??? hah, I got the scoop
02:42:40 Michael:??? I got delicious food?
结果显而易见, 首先是Tityz拿到勺子, 但是因为"舀"比较花时间, 其他人都只能等. 不过一段时间(1s)过去了, 其他人忍不住了, "抢"了他的勺子, 而Michael则被叫去做其他事情了. 得渔利者Yutting也. Yutting搞定后, Tityz再次抢到勺子(这里的次序是随机的), 这次没人打断他了, Michael则最后才喝到汤.
例子完了, 但是我们应该考虑到问题是, 这个锁定, 到底锁定的对象是什么? ReentrantLock.lock()没有参数, 不想synchronized(xx)可以指定被锁定的对象. 那么我们只能假设ReentrantLock.lock()维护了内部的对象. 显然, 如果我们new了好几个ReentrantLock实例并且每个线程分别持有一个, 那么这些线程最终获取的锁定的对象就不是同一个. 这就是上面例子的Party里共用一个ReentrantLock的原因.?
当然, 共用的形式不一定就是通过直接传递ReentrantLock对象给某个线程, 也可以是在线程执行的方法去共用ReentrantLock, 自己发挥想象力吧
同时也说一下上面代码的缺点, 留意一下上面代码Lunch.dip()的方法签名, public boolean dip(), 是带有返回值的, 这样的做法可谓喜忧参半, 好的一面是, 如果失败了, 调用该方法的线程有机会进行其他事情的处理, 不利的一面是调用该方法的线程被逼要使用不断尝试的方式来处理, 增加了代码复杂度.
我们有一种解决上述问题的做法, 就是让调用的线程等待, 直到条件满足为止. 可以参考java.util.concurrent.locks.Condition类的使用例子.