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

网友投稿 382 2023-03-26


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

细粒度锁:

java中的几种锁:synchronized,ReentrantLock,ReentrantReadWriteLock已基本可以满足编程需求,但其粒度都太大,同一时刻只有一个线程能进入同步块,这对于某些高并发的场景并不SCvUix适用。比如银行客户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 userMap=new ConcurrentHashMap();

//用户金额map

private static ConcurrentHashMap moneyMap=new ConcurrentHashMap();

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;

}

@SCvUixOverride

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

--SCvUix-----sleep4s--------u2

-------awake----------u2

u2-------moneny----------5

-------sleep4s--------u2

-------awake----------u2

u2-------moneny----------6

测试结果来看,只有相同userId的线程才会互斥,同步等待;不同userId的线程没有同步

总结

以上就是本文关于java基于ConcurrentHashMap设计细粒度实现代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:权限控制之粗粒度与细粒度概念及实现简单介绍、javaweb设计中filter粗粒度权限控制代码示例等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java获取版本号及字节码编译版本方法示例
下一篇:接口测试用例实例分析题(接口测试 用例)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~