package railo.commons.lock.rw;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import railo.commons.lock.LockException;
import railo.commons.lock.LockInterruptedException;
public class RWLock<L> {
private final ReentrantReadWriteLock rwl;
private final Lock rl;
private final Lock wl;
private L label;
private int count;
public RWLock(L label) {
rwl=new ReentrantReadWriteLock(true);
rl = rwl.readLock();
wl = rwl.writeLock();
this.label=label;
}
public void lock(long timeout, boolean readOnly) throws LockException, LockInterruptedException {
if(timeout<=0) throw new LockException("timeout must be a postive number");
try {
if(!getLock(readOnly).tryLock(timeout, TimeUnit.MILLISECONDS)){
throw new LockException(timeout);
}
}
catch (InterruptedException e) {
throw new LockInterruptedException(e);
}
}
synchronized void inc(){
count++;
}
synchronized void dec(){
count--;
}
public void unlock(boolean readOnly) {
//print.e("unlock:"+readOnly);
getLock(readOnly).unlock();
}
private java.util.concurrent.locks.Lock getLock(boolean readOnly) {
return readOnly?rl:wl;
}
/**
* Returns an estimate of the number of threads waiting to
* acquire this lock. The value is only an estimate because the number of
* threads may change dynamically while this method traverses
* internal data structures. This method is designed for use in
* monitoring of the system state, not for synchronization
* control.
*
* @return the estimated number of threads waiting for this lock
*/
public int getQueueLength() {
return count;
}
/**
* Queries if the write lock is held by any thread.
*/
public boolean isWriteLocked(){
return rwl.isWriteLocked();
}
/**
* Queries if one or more write lock is held by any thread.
*/
public boolean isReadLocked(){
return rwl.getReadLockCount()>0;
}
public L getLabel(){
return label;
}
}