Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现自旋锁以避免阻塞_Java_Multithreading_Thread Synchronization_Spinlock - Fatal编程技术网

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

Java 如何实现自旋锁以避免阻塞,java,multithreading,thread-synchronization,spinlock,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已经取得了同步块的所有权,同时如果线程t2试图取得同步块,那么t2将进行内核等待。 我希望避免这种情况,并在块之前旋转t2,直到t1调用等待并离开块

考虑以下代码:

// 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调用等待并离开块的所有权。有可能吗?

是的,有可能做你想做的事

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


要实现等待和通知功能,可以调用方法newCondition on Lock来获取条件对象。Condition接口具有wait和signal/signalAll方法,其工作方式类似于wait和notify/notifyAll。

JVM不需要将锁定的同步块的条目作为硬块和上下文开关实现。事实上,oraclejvm使用户可以避免阻塞。因此,您可能会发现JVM已经为您进行了这种优化。如果没有,那可能是因为JVM有证据表明自旋锁是个坏主意。

它很容易实现。这里的想法是利用锁接口的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();
 }

}

参考资料:

在点击提交之前,请在格式化您的帖子方面投入更多的精力-使用预览查看帖子的外观,并且仅在您回答问题时,当它看起来像您希望的样子时才提交。此外,您是否有证据表明这实际上导致了代码中的问题?自旋锁很少是正确的解决方案-请记住,t1会在调用wait时立即放弃锁,因此t2阻塞的机会窗口非常小。为什么要这样做?相反,在一个线程上等待锁,你会有一个线程在等待锁,同时浪费CPU周期。我对这个代码块的使用太过频繁,多个线程等待并通知,我不希望我的线程进入内核等待,而是希望我可以旋转一点,获得OP应该在why上展开的所有权协议-但是如果从来没有很好的需求,那么就不会创建java.util.concurrent.locks包。谢谢Raedwald,你能分享任何建议这个的链接吗?CAS不需要实现自旋锁。通过while getAndSettrue==true之类的方式更改循环可能会依赖于更简单的xchg指令。但是还有更多的问题,最好依靠JVM来做正确的事情。
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);
   }
}