shz.core.lock.FIFOMutex Maven / Gradle / Ivy
package shz.core.lock;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
import java.util.function.Supplier;
public class FIFOMutex {
private final AtomicBoolean locked = new AtomicBoolean();
private final Queue waiters = new ConcurrentLinkedQueue<>();
protected final void lock() {
boolean interrupted = false;
Thread current = Thread.currentThread();
waiters.add(current);
while (waiters.peek() != current || !locked.compareAndSet(false, true)) {
// 中断后当前线程无法通过park挂起,需要清除中断标志位
LockSupport.park(this);
// 忽略中断,清除中断标志位
interrupted = Thread.interrupted();
}
waiters.remove();
if (interrupted) current.interrupt();
}
protected final void unlock() {
locked.set(false);
// 使当前线程获取到许可证,当前线程依然而可以使用park挂起
LockSupport.unpark(waiters.peek());
}
public final T apply(Supplier extends T> supplier) {
lock();
try {
return supplier.get();
} finally {
unlock();
}
}
public final void accept(Runnable runnable) {
lock();
try {
runnable.run();
} finally {
unlock();
}
}
}