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