java 使用ConcurrentHashMap和计数器实现锁
更新时间:2017年05月27日 14:27:30 投稿:lqh
这篇文章主要介绍了java 使用ConcurrentHashMap和计数器实现锁的相关资料,需要的朋友可以参考下
java 使用ConcurrentHashMap和计数器实现锁
在某些场景下,我们想让线程根据某些业务数据进行排队,简单代码如下:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; public class TestServiceImpl { private static ConcurrentHashMap<Long, LockObj> lockMap = new ConcurrentHashMap<Long, LockObj>(40); public void test(Long userId){ LockObj lock = tryLock(userId); synchronized (lock) { try{ //处理业务 } finally{ unLock(lock); } } } private LockObj tryLock(Long key) { LockObj curVal = new LockObj(key); LockObj preVal = lockMap.putIfAbsent(key, curVal); if (null == preVal) { curVal.inc(); return curVal; } else{ preVal.inc(); } return preVal; } private void unLock(LockObj lock){ if (lock.dec() <= 0){ lockMap.remove(lock.getKey()); } } public class LockObj { private long key = 0; private AtomicInteger count = new AtomicInteger(0); public LockObj(long key){ this.key = key; } public int inc(){ return count.incrementAndGet(); } public int dec(){ return count.decrementAndGet(); } public long getKey(){ return key; } @Override public String toString() { return "LockObj [key=" + key + ", count=" + count + "]"; } } }
按照userId来排队,如果每个线程处理数据后不释放锁的话,那么可以不利用计数器。但是加了释放锁的操作,则必须加上计算器。因为当线程把锁释放掉后,还没来得及退出synchronized 代码块时,另外一个线程调用了tryLock方法,那该线程将拿到另外一个对象的锁,导致利用synchronized 关键字进行userId排队失败。
也可以利用guava的API来实现。
import com.google.common.collect.Interner; import com.google.common.collect.Interners; public class TestServiceImpl { Interner<String> pool = Interners.newWeakInterner(); public void test(Long userId) throws OspException { synchronized ( pool.intern(String.valueOf(userId))){ //处理业务操作 } } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
您可能感兴趣的文章:
相关文章
详解手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)
本篇文章主要介绍了手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版),具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-12-12Java使用JavaMail API发送和接收邮件的代码示例
JavaMail是Oracle甲骨文开发的Java邮件类API,支持多种邮件协议,这里我们就来看一下Java使用JavaMail API发送和接收邮件的代码示例2016-06-06
最新评论