问题
Consider the following code:
// Below block executed by thread t1
synchronized(obj) {
obj.wait(0);
}
// This block executed by thread t2
synchronized(obj) {
obj.notify();
}
I understand that in above code if t1
has taken ownership of synchronized block and at the same time if thread t2
tries to take synchronized block, then t2
goes for a kernel wait.
I want to avoid this situation and spin t2
before the block until t1
calls wait and leaves ownership of the block. Is that possible?
回答1:
The JVM need not implement entry to a locked synchronized block as a hard block and context switch. It has the option of using lighter weight methods, such as spin locks. In fact, the Oracle JVM goes to some lengths to avoid blocking. So you might find that the JVM has already done this optimisation for you. And if it has not, that might be because the JVM has evidence that a spin lock would be a bad idea.
回答2:
Yes, it's possible to do what you want.
An implementation of the interface java.util.concurrent.locks.Lock
(such as ReentrantLock
) allows you to busy-wait for a lock using the tryLock
method (invoked from a loop).
To implement wait
and notify
functionality, you call the method newCondition
on Lock
to obtain a Condition
object. The Condition
interface has the methods await
and signal
/signalAll
that work analogous to wait
and notify
/notifyAll
.
回答3:
Its very easy to implement spinlock in Java. The idea here is to take advantage of tryLock() method of Lock interface.
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();
}
}
Reference: https://tech693.blogspot.com/2018/08/java-spin-lock-implementation.html
回答4:
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);
}
}
来源:https://stackoverflow.com/questions/26709471/how-to-implement-a-spinlock-to-avoid-blocking