package com.haogrgr.test.util; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 可以参考Guava的Striped * * @author desheng.tu * @since 2015年8月30日 下午1:12:31 * */ public class ConCurrentLockFetch { private AtomicLong[] excepts; private AtomicLong[] values; private ConcurrentHashMap<String, ReentrantLock> lockMap; public ConCurrentLockFetch(Integer threadNum) { for (int i = 0; i < threadNum; i++) { excepts[i] = new AtomicLong(); values[i] = new AtomicLong(); } lockMap = new ConcurrentHashMap<String, ReentrantLock>(threadNum); } public Lock getLock(String key){ int index = Math.abs(key.hashCode() % values.length); long except = excepts[index].getAndIncrement(); AtomicLong value = values[index]; while(true){ if(value.get() == except){ ReentrantLock lock = getRealLock(key); value.set(except + 1); return lock; } } } public void releaseLock(String key, ReentrantLock lock){ ReentrantLock original = lockMap.get(key); if(lock == original){ lockMap.remove(key); } } private ReentrantLock getRealLock(String key){ ReentrantLock lock = lockMap.get(key); if(lock == null){ lock = new ReentrantLock(); lockMap.put(key, lock); } return lock; } }