请考虑以下代码:
// 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并离开该块的所有权。这可能吗?
答案 0 :(得分:0)
是的,可以做你想做的事。
接口java.util.concurrent.locks.Lock
的实现(例如ReentrantLock
)允许您使用tryLock
方法(从循环调用)忙等待锁定。
要实施wait
和notify
功能,请调用newCondition
上的方法Lock
以获取Condition
个对象。 Condition
界面的方法await
和signal
/ signalAll
的工作方式类似于wait
和notify
/ 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);
}
}