package uk.ac.ic.wlgitbridge.data; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Created by Winston on 20/11/14. */ public class ProjectLock { private final Map<String, Lock> projectLocks; private final ReentrantReadWriteLock rwlock; private final Lock rlock; private final ReentrantReadWriteLock.WriteLock wlock; private LockAllWaiter waiter; private boolean waiting; public ProjectLock() { projectLocks = new HashMap<String, Lock>(); rwlock = new ReentrantReadWriteLock(); rlock = rwlock.readLock(); wlock = rwlock.writeLock(); waiting = false; } public void lockForProject(String projectName) { getLockForProjectName(projectName).lock(); rlock.lock(); } public void unlockForProject(String projectName) { getLockForProjectName(projectName).unlock(); rlock.unlock(); if (waiting) { trySignal(); } } private void trySignal() { int threads = rwlock.getReadLockCount(); if (waiter != null && threads > 0) { waiter.threadsRemaining(threads); } } public void lockAll() { waiting = true; trySignal(); wlock.lock(); } private synchronized Lock getLockForProjectName(String projectName) { Lock lock = projectLocks.get(projectName); if (lock == null) { lock = new ReentrantLock(); projectLocks.put(projectName, lock); } return lock; } public void setWaiter(LockAllWaiter waiter) { this.waiter = waiter; } }