可以`LockSupport.park()`替换`Object.wait()`?

时间:2016-09-09 16:06:22

标签: java multithreading locking wait

目前我正在学习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()做得更好的方面,如表现?

2 个答案:

答案 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();

在没有同步或其他保护的情况下,其他一些线程可以更改这两行代码之间的条件变量。因此,您的代码可能会在不应该停放/取消停放的情况下停放/取消停放。