时间:2021-05-19
细粒度锁:
java中的几种锁:synchronized,ReentrantLock,ReentrantReadWriteLock已基本可以满足编程需求,但其粒度都太大,同一时刻只有一个线程能进入同步块,这对于某些高并发的场景并不适用。比如银行客户a向b转账,c向d转账,假如这两个线程并发,代码其实不需要同步。但是同时有线程3,e向b转账,那么对b而言必须加入同步。这时需要考虑锁的粒度问题,即细粒度锁。
网上搜寻了一些关于java细粒度锁的介绍文章,大部分是提供思路,比如乐观锁,String.intern()和类ConcurrentHashMap,本人对第三种比较感兴趣,为此研究了下ConcurrentHashMap的源码。基于ConcurrentHashMap设计细粒度大志思路如下:
Map locks = new Map(); List lockKeys = new List();for (int number : 1 - 10000) { Object lockKey = new Object(); lockKeys.add(lockKey); locks.put(lockKey, new Object());}public void doSomeThing(String uid) { Object lockKey = lockKeys.get(uid.hash() % lockKeys.size()); Object lock = locks.get(lockKey); synchronized(lock) { // do something }}具体实现如下:
public class LockPool { //用户map private static ConcurrentHashMap<String,Object> userMap=new ConcurrentHashMap<String,Object>(); //用户金额map private static ConcurrentHashMap<String,Integer> moneyMap=new ConcurrentHashMap<String,Integer>(); public static void main(String[] args) { LockPool lockPool=new LockPool(); ExecutorService service = Executors.newCachedThreadPool(); service.execute(lockPool.new Boss("u2")); service.execute(lockPool.new Boss("u1")); service.execute(lockPool.new Boss("u1")); service.execute(lockPool.new Boss("u3")); service.execute(lockPool.new Boss("u2")); service.execute(lockPool.new Boss("u2")); service.execute(lockPool.new Boss("u3")); service.execute(lockPool.new Boss("u2")); service.execute(lockPool.new Boss("u2")); service.execute(lockPool.new Boss("u4")); service.execute(lockPool.new Boss("u2")); service.shutdown(); } class Boss implements Runnable{ private String userId; Boss(String userId){ this.userId=userId; } @Override public void run() { addMoney(userId); } } public static void addMoney(String userId){ Object obj=userMap.get(userId); if(obj==null){ obj=new Object(); userMap.put(userId,obj); } //obj是与具体某个用户绑定,这里应用了synchronized(obj)的小技巧,而不是同步当前整个对象 synchronized (obj) { try { System.out.println("-------sleep4s--------"+userId); Thread.sleep(4000); System.out.println("-------awake----------"+userId); } catch (InterruptedException e) { e.printStackTrace(); } if(moneyMap.get(userId)==null){ moneyMap.put(userId,1); } else{ moneyMap.put(userId, moneyMap.get(userId)+1); } System.out.println(userId+"-------moneny----------"+moneyMap.get(userId)); } }}测试结果:
测试结果来看,只有相同userId的线程才会互斥,同步等待;不同userId的线程没有同步
总结
以上就是本文关于java基于ConcurrentHashMap设计细粒度实现代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:权限控制之粗粒度与细粒度概念及实现简单介绍、javaweb设计中filter粗粒度权限控制代码示例等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
apacheshiro是一个功能强大且灵活的开放源代码安全框架,可以细粒度地处理认证(authentication),授权(authorization),会话(
本文实例讲述了Java基于享元模式实现五子棋游戏功能。分享给大家供大家参考,具体如下:一、模式定义享元模式,以共享的方式高效地支持大量的细粒度对象。通过复用内存
一、定义面向对象设计鼓励将行为分布到各个对象中,把对象划分成更小的粒度,有助于增强对象的可复用性。但由于这些细粒度对象之间的联系激增,又可能反过来降低它们的可复
本文实例讲述了javascript设计模式之享元模式。分享给大家供大家参考,具体如下:享元模式说明定义:用于解决一个系统大量细粒度对象的共享问题:关健词:分离跟
日志记录器(Logger)是日志处理的核心组件。log4j具有5种正常级别(Level)。1.staticLevelDEBUG:DEBUGLevel指出细粒度信