使用ZooKeeper實現Java跨JVM的分佈式鎖(優化構思)

1、使用ZooKeeper實現Java跨JVM的分佈式鎖java

2、使用ZooKeeper實現Java跨JVM的分佈式鎖(優化構思)node

3、使用ZooKeeper實現Java跨JVM的分佈式鎖(讀寫鎖)redis

 

說明:這篇文章是基於 使用ZooKeeper實現Java跨JVM的分佈式鎖 的,沒有閱讀的朋友請先閱讀前面的文章後在閱讀本文。apache

上一篇文章中介紹瞭如何使用分佈式鎖,而且對原來的公平鎖進行了擴展,實現了非公平鎖,已經可以知足大部分跨進程(JVM)鎖的需求了。緩存

 

問題:咱們都知道在單個JVM內部實現鎖的機制很方便,Java也提供了很豐富的API能夠實現,例如Synchronized關鍵字, ReentrantLock等等,可是在集羣環境中,都是多個JVM協同工做,當須要一些全局鎖時就要用到上面介紹的分佈式鎖了,可是這種鎖的缺點在於每次客戶端(這裏說的客戶端能夠理解爲不一樣JVM當中的線程)須要獲取鎖時都須要與zook服務端交互,建立znode,等待着本身獲取鎖,這種網絡通訊無疑會給服務器帶來必定的壓力,那麼咱們有沒有什麼辦法來減小這種壓力呢?服務器

 

場景:有一種很常見的場景就是更新緩存,那麼咱們通常的處理邏輯以下。網絡

一、 首選根據key獲取資源,若是資源存在,用之。併發

二、若是不存在,則申請獲取鎖(使用共享鎖)。jvm

三、獲取到鎖之後,再次判斷資源是否存在(防止重複更新),若是存在說明已經有人更新了,方法退出,不然更新緩存。分佈式

四、釋放鎖。

假設如今有10(1-10)個線程同時執行上訴邏輯,若是資源不存在,那麼它們所有會執行第(2)步獲取鎖,在同一時刻,只會有1個線程獲取鎖,其它9個線程阻塞,等待獲取鎖。如今咱們假設線程1獲取到鎖,開始執行(3-4)步動做,在第(3步)當中,再次判斷資源是否存在,(確定不存在由於它是第一個進去的),因此它負責加載資源放入緩存,而後釋放鎖, 再說其它線程(2-10)它們依次獲取到鎖,而後執行(3,4)動做,再次判斷資源是否存在(已經存在了,由於1號線程已經放進去了),因此他們直接退出,釋放鎖。因而可知只有1號線程獲取鎖是有意義的,可是它們都須要與zook進行網絡通信,所以會給網絡帶來壓力。

 

若是說咱們有A,B 二臺服務器進行集羣,這10個線程獲取鎖的請求分別來自這2臺服務器,例如(1-5)號線程來自A服務器, (6-10)號線程來自B服務器,那麼它們與zk交互了10次,建立10個znode來申請鎖,可是若是咱們進行必定的優化,它們只要與zk交互2次就夠了,咱們來把上面的邏輯改造一下。

 

一、 首選根據key獲取資源,若是資源存在,用之。

二、若是不存在,則申請獲取鎖(JVM進程內的鎖)。

三、獲取到鎖(JVM進程內的鎖),再次判斷資源是否存在,若是資源存在就退出,沒啥好所的。

四、若是資源不存在,則申請獲取鎖(分佈式鎖)。

五、獲取到鎖(分佈式鎖)再次判斷資源是否存在(防止重複更新),若是存在說明已經有人更新了,方法退出,不然更新緩存。

六、釋放分佈式鎖,釋放JVM進程內的鎖。

 

代碼:我把實現邏輯都放在一塊兒了,方便給你們演示,若是有邏輯錯誤歡迎你們留言指正。

 

[java]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. package com.framework.code.demo.zook;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import java.util.concurrent.ExecutorService;  
  6. import java.util.concurrent.Executors;  
  7. import java.util.concurrent.TimeUnit;  
  8. import java.util.concurrent.locks.ReentrantLock;  
  9.   
  10. import org.apache.curator.framework.CuratorFramework;  
  11. import org.apache.curator.framework.CuratorFrameworkFactory;  
  12. import org.apache.curator.framework.recipes.locks.InterProcessMutex;  
  13. import org.apache.curator.retry.ExponentialBackoffRetry;  
  14.   
  15. import com.framework.code.demo.zook.lock.NoFairLockDriver;  
  16.   
  17. public class Main {  
  18.       
  19.     //咱們用一個static的map模擬一個第三方獨立緩存  
  20.     public static Map<String, Object> redis = new HashMap<String, Object>();  
  21.     public static final String key = "redisKey";  
  22.       
  23.     public static void main(String[] args) throws InterruptedException {  
  24.         //建立倆個對象分別模擬2個進程  
  25.         RedisProcess processA = new RedisProcess();  
  26.         RedisProcess processB = new RedisProcess();  
  27.           
  28.         //每一個進程別分用50個線程併發請求  
  29.         ExecutorService service = Executors.newFixedThreadPool(100);  
  30.         for (int i = 0; i < 50; i++) {  
  31.             service.execute(processA);  
  32.             service.execute(processB);  
  33.         }  
  34.           
  35.         service.shutdown();  
  36.         service.awaitTermination(30, TimeUnit.SECONDS);  
  37.     }  
  38.       
  39.     public static class RedisProcess implements Runnable {  
  40.         CuratorFramework client;  
  41.         //ZK分佈式鎖  
  42.         InterProcessMutex distributedLock;  
  43.         //JVM內部鎖  
  44.         ReentrantLock jvmLock;  
  45.           
  46.         public RedisProcess() {  
  47.             client = CuratorFrameworkFactory.newClient("192.168.1.18:2181",   
  48.                     new ExponentialBackoffRetry(1000,3));  
  49.             client.start();  
  50.             distributedLock = new InterProcessMutex(client,"/mylock", new NoFairLockDriver());  
  51.             jvmLock = new ReentrantLock();  
  52.         }  
  53.   
  54.         @Override  
  55.         public void run() {  
  56.             //(1)首先判斷緩存內資源是否存在  
  57.             if(redis.get(key) == null) {  
  58.                 try {  
  59.                       
  60.                     //這裏延時1000毫秒的目的是防止線程過快的更新資源,那麼其它線程在步驟(1)處就返回true了.  
  61.                     Thread.sleep(1000);  
  62.                       
  63.                     //獲取JVM鎖(同一進程內有效)  
  64.                     jvmLock.lock();  
  65.                       
  66.                     //(2)再次判斷資源是否已經存在  
  67.                     if(redis.get(key) == null) {  
  68.                         System.out.println("線程:" + Thread.currentThread() + "獲取到JVM鎖,redis.get(key)爲空, 準備獲取ZK鎖");  
  69.                           
  70.                         //這裏延時500毫秒的目的是防止線程過快更新資源,其它線程在步驟(2)就返回true了。  
  71.                         Thread.sleep(500);  
  72.                         try {  
  73.                             //獲取zk分佈式鎖  
  74.                             distributedLock.acquire();  
  75.                             System.out.println("線程:" + Thread.currentThread() + "獲取到JVM鎖,redis.get(key)爲空, 獲取到了ZK鎖");  
  76.   
  77.                             //再次判斷,若是爲空這時能夠更新資源  
  78.                             if(redis.get(key) == null) {  
  79.                                 redis.put(key, Thread.currentThread() + "更新了緩存");  
  80.                                 System.out.println("線程:" + Thread.currentThread() + "更新了緩存");  
  81.                             } else {  
  82.                                 System.out.println("線程:" + Thread.currentThread() + "當前資源已經存在,不須要更新");  
  83.                             }  
  84.                         } catch (Exception e) {  
  85.                             e.printStackTrace();  
  86.                         } finally {  
  87.                             //釋放ZK鎖  
  88.                             try {  
  89.                                 distributedLock.release();  
  90.                             } catch (Exception e) {  
  91.                                 e.printStackTrace();  
  92.                             }  
  93.                         }  
  94.                     } else {  
  95.                         System.out.println("線程:" + Thread.currentThread() + "獲取到JVM鎖,redis.get(key)不爲空," + redis.get(key));  
  96.                     }  
  97.                 } catch (InterruptedException e) {  
  98.                     e.printStackTrace();  
  99.                 } finally {  
  100.                     //釋放JVM鎖  
  101.                     jvmLock.unlock();  
  102.                 }  
  103.             } else {  
  104.                 System.out.println(redis.get(key));  
  105.             }  
  106.         }  
  107.     }  
  108.   
  109. }  



 

 

線程:Thread[pool-5-thread-2,5,main]獲取到JVM鎖,redis.get(key)爲空, 準備獲取ZK鎖
線程:Thread[pool-5-thread-3,5,main]獲取到JVM鎖,redis.get(key)爲空, 準備獲取ZK鎖
線程:Thread[pool-5-thread-3,5,main]獲取到JVM鎖,redis.get(key)爲空, 獲取到了ZK鎖
線程:Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-7,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-1,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-5,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-9,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-23,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-19,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-11,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-31,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-35,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-15,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-27,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-25,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-33,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-37,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-13,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-17,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-2,5,main]獲取到JVM鎖,redis.get(key)爲空, 獲取到了ZK鎖
線程:Thread[pool-5-thread-2,5,main]當前資源已經存在,不須要更新
線程:Thread[pool-5-thread-21,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-29,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-55,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-59,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-41,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-67,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-39,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-43,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-57,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-47,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-51,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-63,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-8,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-69,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-4,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-6,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-10,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-22,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-16,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-20,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-45,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-24,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-32,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-36,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-49,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-28,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-12,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-14,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-26,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-53,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-18,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-61,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-30,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-65,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-34,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-97,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-40,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-91,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-64,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-42,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-46,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-50,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-87,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-85,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-44,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-75,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-48,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-71,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-77,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-52,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-99,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-93,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-56,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-60,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-95,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-89,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-81,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-73,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-68,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-58,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-62,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-66,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-38,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-54,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-94,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-83,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-96,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-79,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-92,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-90,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-80,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-82,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-72,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-78,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-100,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-70,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-88,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-84,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-98,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-86,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-76,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存
線程:Thread[pool-5-thread-74,5,main]獲取到JVM鎖,redis.get(key)不爲空,Thread[pool-5-thread-3,5,main]更新了緩存

咱們經過觀察日誌,發現只有2個次須要獲取分佈式鎖,其它的都被JVM鎖給阻擋在外面了,在這種狀況下能夠大大的提升鎖的性能。

相關文章
相關標籤/搜索