Skip to content

Instantly share code, notes, and snippets.

@basilevs
Created July 27, 2021 08:15
Show Gist options
  • Save basilevs/36854400bc2b574abe9fe165db8c1172 to your computer and use it in GitHub Desktop.
Save basilevs/36854400bc2b574abe9fe165db8c1172 to your computer and use it in GitHub Desktop.
Explain concurrency error
import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
/** Executes a runnable as a critical section but without any blocking.
* Number of executions is not guaranteed to match a number of invocations.
* Last invocation happens-before last execution.
*
* **/
public final class ExclusiveRunner implements Runnable {
private final Runnable delegate;
private final AtomicBoolean requested = new AtomicBoolean(false);
private final Semaphore semaphore = new Semaphore(1);
public ExclusiveRunner(Runnable delegate) {
super();
this.delegate = Objects.requireNonNull(delegate);
}
@Override
public void run() {
requested.set(true);
while (requested.get() && semaphore.tryAcquire()) { // Can't tryAcquire() fail spuriously?
try {
if (requested.getAndSet(false)) {
delegate.run();
}
} finally {
semaphore.release();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment