1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util;
20
21
22 import java.util.Arrays;
23 import java.util.LinkedHashMap;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.concurrent.locks.Lock;
27 import java.util.concurrent.locks.ReentrantLock;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.hbase.classification.InterfaceAudience;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 @InterfaceAudience.Private
50 public class KeyLocker<K> {
51 private static final Log LOG = LogFactory.getLog(KeyLocker.class);
52
53
54 private static final int NB_CONCURRENT_LOCKS = 1000;
55
56 private final WeakObjectPool<K, ReentrantLock> lockPool =
57 new WeakObjectPool<K, ReentrantLock>(
58 new WeakObjectPool.ObjectFactory<K, ReentrantLock>() {
59 @Override
60 public ReentrantLock createObject(K key) {
61 return new ReentrantLock();
62 }
63 },
64 NB_CONCURRENT_LOCKS);
65
66
67
68
69
70
71 public ReentrantLock acquireLock(K key) {
72 if (key == null) throw new IllegalArgumentException("key must not be null");
73
74 lockPool.purge();
75 ReentrantLock lock = lockPool.get(key);
76
77 lock.lock();
78 return lock;
79 }
80
81
82
83
84
85
86
87
88 public Map<K, Lock> acquireLocks(Set<? extends K> keys) {
89 Object[] keyArray = keys.toArray();
90 Arrays.sort(keyArray);
91
92 lockPool.purge();
93 Map<K, Lock> locks = new LinkedHashMap<K, Lock>(keyArray.length);
94 for (Object o : keyArray) {
95 @SuppressWarnings("unchecked")
96 K key = (K)o;
97 ReentrantLock lock = lockPool.get(key);
98 locks.put(key, lock);
99 }
100
101 for (Lock lock : locks.values()) {
102 lock.lock();
103 }
104 return locks;
105 }
106 }