如何实现自旋锁以避免阻塞

时间:2014-11-03 07:16:15

标签: java multithreading thread-synchronization spinlock

请考虑以下代码:

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

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

我理解在上面的代码中,如果t1取得了synchronized块的所有权,同时如果线程t2尝试获取synchronized块,那么t2将用于内核等待。 我想避免这种情况并在阻塞之前旋转t2,直到t1调用wait并离开该块的所有权。这可能吗?

4 个答案:

答案 0 :(得分:0)

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

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

要实施waitnotify功能,请调用newCondition上的方法Lock以获取Condition个对象。 Condition界面的方法awaitsignal / signalAll的工作方式类似于waitnotify / notifyAll。< / p>

答案 1 :(得分:0)

JVM无需实现作为硬块和上下文切换的锁定同步块的条目。 It has the option of using lighter weight methods, such as spin locks。事实上,Oracle JVM转到some lengths以避免阻塞。所以你可能会发现JVM已经为你做了这个优化。如果没有,那可能是因为JVM有证据表明自旋锁是一个坏主意。

答案 2 :(得分:-1)

实施spinlock in Java非常容易。这里的想法是利用Lock接口的tryLock()方法。

 import java.util.concurrent.locks.ReentrantLock;

public class SpinLock extends ReentrantLock{

public SpinLock() {
  super();
 }


 public void lock() {
  while(!super.tryLock()) {
    // Do Nothing
  }

 }

 public void unlock() {
  super.unlock();
 }

}

参考:https://tech693.blogspot.com/2018/08/java-spin-lock-implementation.html

答案 3 :(得分:-1)

import java.util.concurrent.atomic.AtomicBoolean;

public class SpinLock {

   private AtomicBoolean locked = new AtomicBoolean(false);

   public void lock() {
      while (!locked.compareAndSet(false, true));
   }

   public void unlock() {
      locked.set(false);
   }
}