目前我正在学习Java中的并发编程。我注意到Java 1.6中引入的LockSupport.park()
比Object.wait()
要容易得多,Object.wait()
的典型用法就像
// Thread1
synchronized (lock) {
while (condition != true) {
lock.wait()
}
// do stuff
}
// Thread2
synchronized (lock) {
condition = true;
lock.notify();
}
我认为我可以使用LockSupport.park()
来重写它,如
// Thread1
while (condition != true) {
LockSupport.park();
}
// do stuff
// Thread2
condition = true;
LockSupport.unpark(Thread1);
使用LockSupport.park()
,繁琐的synchroinzed
块消失。
我的问题是,我是否应该总是更喜欢LockSupport.park()
而不是Object.wait()
?是否有Object.wait()
比LockSupport.park()
做得更好的方面,如表现?
答案 0 :(得分:5)
wait / notify背后的想法是通知不是特定于线程的,通知程序不必知道需要通知的特定线程,它只是告诉锁定(或条件,对于ReentrantLock)它正在通知,它们之间的锁和OS调度程序决定谁获得通知。
我希望通知程序大多数时候都不想知道哪个线程需要取消停放,所以wait / notify对于那些情况来说是更好的选择。使用park / unpark,您的代码必须了解更多,并且会有更多失败的机会。你可能认为同步的块是单调乏味的,但真正繁琐的是整理出某些东西在它应该没有停放的情况。
请注意,在您的第二个示例中,您的条件需要是volatile或Atomic,或者是其他更新在线程中可见的内容。
答案 1 :(得分:0)
不,Locksupport.park()/unpark() 不能替代 Object.wait()。
Locksupport.park()/unpark() 不需要您获取锁,但 Object.wait() 确实需要您使用 synchronized 关键字来保护它。让我告诉你为什么,
while (condition != true)
LockSupport.park();
在没有同步或其他保护的情况下,其他一些线程可以更改这两行代码之间的条件变量。因此,您的代码可能会在不应该停放/取消停放的情况下停放/取消停放。