源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

java基于ConcurrentHashMap设计细粒度实现代码

  • 时间:2021-05-20 13:41 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:java基于ConcurrentHashMap设计细粒度实现代码
[b]细粒度锁: [/b]        java中的几种锁:[url=http://www.1sucai.cn/article/124023.htm]synchronized[/url],ReentrantLock,ReentrantReadWriteLock已基本可以满足编程需求,但其粒度都太大,同一时刻只有一个线程能进入同步块,这对于某些高并发的场景并不适用。比如银行客户a向b转账,c向d转账,假如这两个线程并发,代码其实不需要同步。但是同时有线程3,e向b转账,那么对b而言必须加入同步。这时需要考虑锁的粒度问题,即细粒度锁。     网上搜寻了一些关于java细粒度锁的介绍文章,大部分是提供思路,比如[url=http://www.1sucai.cn/article/124745.htm]乐观锁[/url],String.intern()和类ConcurrentHashMap,本人对第三种比较感兴趣,为此研究了下ConcurrentHashMap的源码。[b]基于ConcurrentHashMap设计细粒度大志思路如下[/b]:
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));
  }
 }
}
 测试结果:
-------sleep4s--------u2
-------sleep4s--------u1
-------sleep4s--------u3
-------sleep4s--------u4
-------awake----------u2
-------awake----------u3
-------awake----------u1
u2-------moneny----------1
u1-------moneny----------1
-------sleep4s--------u1
u3-------moneny----------1
-------sleep4s--------u2
-------sleep4s--------u3
-------awake----------u4
u4-------moneny----------1
-------awake----------u1
u1-------moneny----------2
-------awake----------u3
u3-------moneny----------2
-------awake----------u2
u2-------moneny----------2
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------3
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------4
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------5
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------6
测试结果来看,只有相同userId的线程才会互斥,同步等待;不同userId的线程没有同步 [b]总结[/b] 以上就是本文关于java基于ConcurrentHashMap设计细粒度实现代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:[url=http://www.1sucai.cn/article/125782.htm]权限控制之粗粒度与细粒度概念及实现简单介绍[/url]、[url=http://www.1sucai.cn/article/125781.htm]javaweb设计中filter粗粒度权限控制代码示例[/url]等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部