|
@@ -4,6 +4,7 @@ import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.locks.Lock;
|
|
import java.util.concurrent.locks.Lock;
|
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
|
+import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Created by Winston on 20/11/14.
|
|
* Created by Winston on 20/11/14.
|
|
@@ -11,17 +12,44 @@ import java.util.concurrent.locks.ReentrantLock;
|
|
|
public class ProjectLock {
|
|
public class ProjectLock {
|
|
|
|
|
|
|
|
private final Map<String, Lock> projectLocks;
|
|
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() {
|
|
public ProjectLock() {
|
|
|
projectLocks = new HashMap<String, Lock>();
|
|
projectLocks = new HashMap<String, Lock>();
|
|
|
|
|
+ rwlock = new ReentrantReadWriteLock();
|
|
|
|
|
+ rlock = rwlock.readLock();
|
|
|
|
|
+ wlock = rwlock.writeLock();
|
|
|
|
|
+ waiting = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void lockForProject(String projectName) {
|
|
public void lockForProject(String projectName) {
|
|
|
getLockForProjectName(projectName).lock();
|
|
getLockForProjectName(projectName).lock();
|
|
|
|
|
+ rlock.lock();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void unlockForProject(String projectName) {
|
|
public void unlockForProject(String projectName) {
|
|
|
getLockForProjectName(projectName).unlock();
|
|
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) {
|
|
private synchronized Lock getLockForProjectName(String projectName) {
|
|
@@ -33,4 +61,8 @@ public class ProjectLock {
|
|
|
return lock;
|
|
return lock;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public void setWaiter(LockAllWaiter waiter) {
|
|
|
|
|
+ this.waiter = waiter;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|