org.jgroups.util.CondVar Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including
all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and
JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
package org.jgroups.util;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BooleanSupplier;
/**
* A condition variable with methods for (timed) waiting and signalling
* @author Bela Ban
* @since 3.6
*/
public class CondVar {
protected final Lock lock;
protected final java.util.concurrent.locks.Condition cond;
public CondVar() {
lock=new ReentrantLock();
cond=lock.newCondition();
}
public CondVar(final Lock lock) {
this.lock=lock;
cond=lock.newCondition();
}
/**
* Blocks until condition is true.
* @param condition The condition. Must be non-null
*/
public void waitFor(BooleanSupplier condition) {
boolean intr=false;
lock.lock();
try {
while(!condition.getAsBoolean()) {
try {
cond.await();
}
catch(InterruptedException e) {
intr=true;
}
}
}
finally {
lock.unlock();
if(intr) Thread.currentThread().interrupt();
}
}
/**
* Blocks until condition is true or the time elapsed
* @param condition The condition
* @param timeout The timeout to wait. A value <= 0 causes immediate return
* @param unit TimeUnit
* @return The condition's status
*/
public boolean waitFor(BooleanSupplier condition, long timeout, TimeUnit unit) {
boolean intr=false;
final long timeout_ns=TimeUnit.NANOSECONDS.convert(timeout, unit);
lock.lock();
try {
for(long wait_time=timeout_ns, start=System.nanoTime(); wait_time > 0 && !condition.getAsBoolean();) {
try {
wait_time=cond.awaitNanos(wait_time);
}
catch(InterruptedException e) {
wait_time=timeout_ns - (System.nanoTime() - start);
intr=true;
}
}
return condition.getAsBoolean();
}
finally {
lock.unlock();
if(intr) Thread.currentThread().interrupt();
}
}
/**
* Wakes up one (signal_all=false) or all (signal_all=true) blocked threads. Usually called when the condition
* changed to true.
* @param signal_all
*/
public void signal(boolean signal_all) {
lock.lock();
try {
if(signal_all)
cond.signalAll();
else
cond.signal();
}
finally {
lock.unlock();
}
}
}