org.apache.hadoop.hbase.util.KeyLocker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hbase-common Show documentation
Show all versions of hbase-common Show documentation
Common functionality for HBase
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.util;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
/**
* A utility class to manage a set of locks. Each lock is identified by a String which serves
* as a key. Typical usage is:
* class Example {
* private final static KeyLocker<String> locker = new Locker<String>();
* public void foo(String s){
* Lock lock = locker.acquireLock(s);
* try {
* // whatever
* }finally{
* lock.unlock();
* }
* }
* }
*
*/
@InterfaceAudience.Private
public class KeyLocker {
// The number of lock we want to easily support. It's not a maximum.
private static final int NB_CONCURRENT_LOCKS = 1000;
private final WeakObjectPool lockPool =
new WeakObjectPool(
new WeakObjectPool.ObjectFactory() {
@Override
public ReentrantLock createObject(K key) {
return new ReentrantLock();
}
},
NB_CONCURRENT_LOCKS);
/**
* Return a lock for the given key. The lock is already locked.
*
* @param key
*/
public ReentrantLock acquireLock(K key) {
if (key == null) throw new IllegalArgumentException("key must not be null");
lockPool.purge();
ReentrantLock lock = lockPool.get(key);
lock.lock();
return lock;
}
/**
* Acquire locks for a set of keys. The keys will be
* sorted internally to avoid possible deadlock.
*
* @throws ClassCastException if the given {@code keys}
* contains elements that are not mutually comparable
*/
public Map acquireLocks(Set extends K> keys) {
Object[] keyArray = keys.toArray();
Arrays.sort(keyArray);
lockPool.purge();
Map locks = new LinkedHashMap(keyArray.length);
for (Object o : keyArray) {
@SuppressWarnings("unchecked")
K key = (K)o;
ReentrantLock lock = lockPool.get(key);
locks.put(key, lock);
}
for (Lock lock : locks.values()) {
lock.lock();
}
return locks;
}
}