0
|
1 package cachingfilter;
|
|
2
|
|
3 import java.util.Map;
|
|
4 import java.util.HashMap;
|
|
5 import java.util.concurrent.locks.Lock;
|
|
6 import java.util.concurrent.locks.ReentrantLock;
|
|
7
|
|
8
|
|
9 public final class Locker<T> {
|
|
10
|
|
11 private static class Tracker {
|
|
12 final ReentrantLock lock = new ReentrantLock();
|
|
13 int waiters = 0;
|
|
14 }
|
|
15
|
|
16 private final Map<T,Tracker> map = new HashMap<T,Tracker>();
|
|
17
|
|
18 public void lock(T obj) {
|
|
19 Tracker t;
|
|
20 synchronized(map) {
|
|
21 t = map.get(obj);
|
|
22 if( t == null ) {
|
|
23 t = new Tracker();
|
|
24 map.put(obj,t);
|
|
25 }
|
|
26 t.waiters++;
|
|
27 }
|
|
28 try {
|
|
29 t.lock.lock();
|
|
30 } finally {
|
|
31 synchronized(map) {
|
|
32 t.waiters--;
|
|
33 }
|
|
34 }
|
|
35 }
|
|
36
|
|
37 public boolean unlock(T obj) {
|
|
38 synchronized(map) {
|
|
39 Tracker t = map.get(obj);
|
|
40 if( t == null || !t.lock.isHeldByCurrentThread() )
|
|
41 return false;
|
|
42 t.lock.unlock();
|
|
43 if( t.waiters==0 ) {
|
|
44 map.remove(obj);
|
|
45 }
|
|
46 return true;
|
|
47 }
|
|
48 }
|
|
49
|
|
50 }
|