Here are three ways, methods, a thread accessing a lock, and one to release a lock. You might want to apply them using the synchronized . The advanced features and benefits of using ReentrantLock will become apparent.
public class DoorLockUsingLock { private int counter= 0; private Thread owner= null; private Lock l = new ReentrantLock(); private Condition notLocked= l.newCondition(); public void lockItDown() throws InterruptedException { l.lockInterruptibly(); try { while ((counter> 0) && (owner!= Thread.currentThread())) { notLocked.await(); } counter++; owner = Thread.currentThread(); } finally { l.unlock(); } } public void lockItDownUninterruptibly() { l.lock(); try { while ((counter > 0) && (owner != Thread.currentThread())) { notLocked.awaitUninterruptibly(); } counter++; owner= Thread.currentThread(); } finally { l.unlock(); } } public boolean tryLockItDown(long timeout, TimeUnit unit) throws InterruptedException { long time = unit.toNanos(timeout); long end = System.nanoTime() + time; boolean success = l.tryLock(timeout, unit); if (!success) { return false; } try { time = end- System.nanoTime(); while ((counter> 0) && (owner != Thread.currentThread()) && (time > 0)) { notLocked.await(time, TimeUnit.NANOSECONDS); time = end - System.nanoTime(); } if (time > 0) { counter++; owner = Thread.currentThread(); return true; } return false; } finally { l.unlock(); } } public void unlockIt() throws IllegalMonitorStateException { l.lock(); try { if (counter== 0) { throw new IllegalMonitorStateException(); } if (owner!= Thread.currentThread()) { throw new IllegalMonitorStateException(); } counter--; if (counter == 0) { owner = null; notLocked.signal(); } } finally { l.unlock(); } } }
source share