Fine-grained locks:
Several locks in Java: Synchronized,reentrantlock,reentrantreadwritelock has basically been able to meet programming needs, but its granularity is too large, at the same time only one thread can enter the synchronization block, This does not apply to certain high concurrency scenarios. For example, bank customer A to B transfer, C to D transfer, if the two threads concurrency, the code actually does not need to synchronize. But at the same time the thread 3,e transfers to B, the synchronization must be added to B. You need to consider the granularity of the lock, that is, fine-grained locks.
Online search for some Java fine-grained lock introduction article, mostly to provide ideas, such as optimistic lock, String.intern () and class Concurrenthashmap, I am interested in the third kind of comparison, Therefore, the source code of the next concurrenthashmap is researched. Based on Concurrenthashmap design fine-grained ambition ideas are as follows:
1Map locks =NewMap (); 2List Lockkeys =NewList (); 3 for(intNumber:1-10000) { 4Object Lockkey =NewObject (); 5 Lockkeys.add (Lockkey); 6Locks.put (Lockkey,NewObject ()); 7 } 8 9 Public voiddosomething (String uid) {TenObject Lockkey = Lockkeys.Get(Uid.hash ()%lockkeys.size ()); OneObjectLock= Locks.Get(Lockkey); A -SynchronizedLock) { - //Do something the } -}
The specific implementation is as follows:
1 Public classLockpool {2 3 //User Map4 Private StaticConcurrenthashmap<string,object> usermap=NewConcurrenthashmap<string,object>();5 //User Amount Map6 Private StaticConcurrenthashmap<string,integer> moneymap=NewConcurrenthashmap<string,integer>();7 8 Public Static voidMain (string[] args) {9Lockpool lockpool=NewLockpool ();TenExecutorservice Service =Executors.newcachedthreadpool (); OneService.execute (Lockpool.NewBoss ("U2")); AService.execute (Lockpool.NewBoss ("U1")); -Service.execute (Lockpool.NewBoss ("U1")); -Service.execute (Lockpool.NewBoss ("U3")); theService.execute (Lockpool.NewBoss ("U2")); -Service.execute (Lockpool.NewBoss ("U2")); -Service.execute (Lockpool.NewBoss ("U3")); -Service.execute (Lockpool.NewBoss ("U2")); +Service.execute (Lockpool.NewBoss ("U2")); -Service.execute (Lockpool.NewBoss ("U4")); +Service.execute (Lockpool.NewBoss ("U2")); A at Service.shutdown (); - - - } - - classBossImplementsrunnable{ in - PrivateString userId; to + Boss (String userId) { - This. userid=userId; the } * $ @OverridePanax Notoginseng Public voidrun () { - Addmoney (userId); the } + A } the + - Public Static voidAddmoney (String userId) { $Object obj=Usermap.get (userId); $ if(obj==NULL){ -obj=NewObject (); - Usermap.put (userid,obj); the }
obj is bound to a specific user, where the synchronized (obj) technique is applied, rather than synchronizing the current entire object - synchronized(obj) {Wuyi Try { theSystem.out.println ("-------sleep4s--------" +userId); -Thread.Sleep (4000); WuSystem.out.println ("-------Awake----------" +userId); -}Catch(interruptedexception e) { About e.printstacktrace (); $ } - if(Moneymap.get (userId) = =NULL){ -Moneymap.put (userid,1); -}Else{ AMoneymap.put (userid, Moneymap.get (userid) +1); + } theSystem.out.println (userid+ "-------moneny----------" +Moneymap.get (userId)); - } $ } the the}
Test Results:
-------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
The test results show that only the same UserID thread will be mutually exclusive, synchronous wait, the thread of different userid is not synchronized
Java Fine-grained locks