2014-11-03 38 views
0

考虑下面的代码:如何实现自旋锁,以避免阻塞

// Below block executed by thread t1 
synchronized(obj) { 
    obj.wait(0); 
} 

// This block executed by thread t2 
synchronized(obj) { 
    obj.notify(); 
} 

据我所知,在上面的代码中,如果t1采取同步块的所有权,并在同一时间,如果线程t2尝试采取同步块,然后t2进入内核等待。 我想避免这种情况,并在块之前旋转t2,直到t1调用等待并且保留块的所有权。那可能吗?

+0

请在提交之前花更多精力来设置您的帖子格式 - 使用预览功能查看帖子的外观,并且只有当它看起来您希望它看起来如果*您*正在回答问题时才提交。 – 2014-11-03 07:17:49

+6

另外,你有证据证明这实际上是在你的代码中造成问题吗?自旋锁很少是正确的解决方案 - 并且牢记,只要调用wait(),t1将立即放弃锁,因此t2阻塞的机会窗口非常小。 – 2014-11-03 07:20:22

+0

你为什么想这样做?相反,在等待锁的一个线程上,您将有一个线程等待锁,同时浪费CPU周期。 – 2014-11-03 08:07:36

回答

1

JVM不需要实现作为硬块和上下文切换的锁定同步块的条目。它可以选择使用较轻重量的方法,如自旋锁。实际上,Oracle JVM需要一些时间来避免阻塞。所以你可能会发现JVM已经为你做了这个优化。如果没有,那可能是因为JVM有证据表明自旋锁将是一个坏主意。

+0

谢谢Raedwald,你能分享任何暗示这一点的链接。 – 2014-11-04 05:59:26

0

是的,可以做你想做的事。

接口java.util.concurrent.locks.Lock(如ReentrantLock)的实现允许您使用tryLock方法(从循环调用)忙等待锁定。

为了实现waitnotify功能,调用方法上LocknewCondition获得Condition对象。 Condition接口具有类似于waitnotify/notifyAll的方法awaitsignal/signalAll