java基于ConcurrentHashMap設計細粒度實現代碼
細粒度鎖:
java中的幾種鎖:synchronized,ReentrantLock,ReentrantReadWriteLock已基本可以滿足編程需求,但其粒度都太大,同一時刻只有一個線程能進入同步塊,這對于某些高并發(fā)的場景并不適用。比如銀行客戶a向b轉賬,c向d轉賬,假如這兩個線程并發(fā),代碼其實不需要同步。但是同時有線程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));
}
}
}
測試結果:
-------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的線程沒有同步
總結
以上就是本文關于java基于ConcurrentHashMap設計細粒度實現代碼的全部內容,希望對大家有所幫助。感興趣的朋友可以參閱:權限控制之粗粒度與細粒度概念及實現簡單介紹、javaweb設計中filter粗粒度權限控制代碼示例等,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
- Java中遍歷ConcurrentHashMap的四種方式詳解
- java 使用ConcurrentHashMap和計數器實現鎖
- Java ConcurrentHashMap的使用示例
- Java源碼解析ConcurrentHashMap的初始化
- java中ConcurrentHashMap的讀操作為什么不需要加鎖
- 基于Java并發(fā)容器ConcurrentHashMap#put方法解析
- java ConcurrentHashMap鎖分段技術及原理詳解
- Java concurrency集合之ConcurrentHashMap_動力節(jié)點Java學院整理
- Java集合ConcurrentHashMap詳解
相關文章
Java使用Scala實現尾遞歸優(yōu)化來解決爆棧問題
Scala?作為一種多范式的編程語言,結合了面向對象和函數式編程的特性,在?Scala?中,尾遞歸?是通過編譯器優(yōu)化來防止棧溢出問題的,尾遞歸優(yōu)化是一種特殊的優(yōu)化方式,可以讓遞歸調用不使用新的棧幀,所以本文介紹了在Java項目中如何使用Scala實現尾遞歸優(yōu)化來解決爆棧問題2024-10-10
springMVC利用FastJson接口返回json數據相關配置詳解
本篇文章主要介紹了springMVC利用FastJson接口返回json數據相關配置詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
Java java.lang.InstantiationException異常案例詳解
這篇文章主要介紹了Java java.lang.InstantiationException異常案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-08-08

