common-utils/src/main/java/org/warp/commonutils/locks/TransitLock.java

54 lines
1.4 KiB
Java

package org.warp.commonutils.locks;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
public class TransitLock {
private final FlexibleCountDownLatch unfinishedTransits = new FlexibleCountDownLatch(0);
private final Semaphore permits = new Semaphore(Integer.MAX_VALUE);
private final AtomicInteger allowedTransits = new AtomicInteger(1);
private final Object synchronization = new Object();
public TransitLock() {
}
public void allowTransit() {
var allowedTransits = this.allowedTransits.incrementAndGet();
if (allowedTransits == 1) {
var permitsToRelease = Math.max(0, Integer.MAX_VALUE - (permits.availablePermits() + 10000));
permits.release(permitsToRelease);
} else if (allowedTransits > 1) {
throw new IllegalStateException("Already allowed transit!");
}
}
public void disallowTransit() {
synchronized (synchronization) {
var allowedTransits = this.allowedTransits.decrementAndGet();
if (allowedTransits == 0) {
unfinishedTransits.await();
permits.drainPermits();
} else if (allowedTransits > 0) {
throw new IllegalStateException("Transits are still allowed for an unknown reason!");
}
}
}
public void transit() {
startTransit();
endTransit();
}
public void startTransit() {
synchronized (synchronization) {
unfinishedTransits.grow();
permits.acquireUninterruptibly();
}
}
public void endTransit() {
unfinishedTransits.countDown();
}
}