001 package railo.commons.lock.rw; 002 003 import java.util.concurrent.TimeUnit; 004 import java.util.concurrent.locks.Lock; 005 import java.util.concurrent.locks.ReentrantReadWriteLock; 006 007 import railo.commons.lock.LockException; 008 import railo.commons.lock.LockInterruptedException; 009 010 public class RWLock<L> { 011 012 private final ReentrantReadWriteLock rwl; 013 private final Lock rl; 014 private final Lock wl; 015 016 private L label; 017 private int count; 018 019 public RWLock(L label) { 020 rwl=new ReentrantReadWriteLock(true); 021 rl = rwl.readLock(); 022 wl = rwl.writeLock(); 023 this.label=label; 024 } 025 026 027 public void lock(long timeout, boolean readOnly) throws LockException, LockInterruptedException { 028 if(timeout<=0) throw new LockException("timeout must be a postive number"); 029 try { 030 if(!getLock(readOnly).tryLock(timeout, TimeUnit.MILLISECONDS)){ 031 throw new LockException(timeout); 032 } 033 } 034 catch (InterruptedException e) { 035 throw new LockInterruptedException(e); 036 } 037 } 038 039 synchronized void inc(){ 040 count++; 041 } 042 synchronized void dec(){ 043 count--; 044 } 045 046 047 public void unlock(boolean readOnly) { 048 //print.e("unlock:"+readOnly); 049 getLock(readOnly).unlock(); 050 } 051 052 private java.util.concurrent.locks.Lock getLock(boolean readOnly) { 053 return readOnly?rl:wl; 054 } 055 056 /** 057 * Returns an estimate of the number of threads waiting to 058 * acquire this lock. The value is only an estimate because the number of 059 * threads may change dynamically while this method traverses 060 * internal data structures. This method is designed for use in 061 * monitoring of the system state, not for synchronization 062 * control. 063 * 064 * @return the estimated number of threads waiting for this lock 065 */ 066 public int getQueueLength() { 067 return count; 068 } 069 070 071 public L getLabel(){ 072 return label; 073 } 074 }