您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關java中各種鎖的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
前言
鎖,顧名思義就是鎖住一些資源,當只有我們拿到鑰匙的時候,才能操作鎖住的資源。在我們的Java,數據庫,還有一些分布式的環境中,總是充斥著各種各樣的鎖讓人頭疼,例如“公平鎖”、“自旋鎖”、“讀寫鎖”、“分布式鎖”等等。
其實真實的情況是,鎖并沒有那么多,很多概念只是從不同的功能特性,設計,以及鎖的狀態這些不同的側重點來說明的,因此我們可以根據不同的分類來搞明白為什么會有這些“鎖”?坐穩扶好了,準備開車。
正文
“公平鎖”與“非公平鎖”
公平鎖:指線程在等待獲取同一個鎖的時候,是嚴格按照申請鎖的時間順序來進行的,這就意味著在程序正常運作的時候,不會有線程執行不到,而被“餓死”,但是也需要額外的機制來維護這種順序,所以效率相對于非公平鎖會差點。
非公平鎖:概念跟“公平鎖”恰恰相反,隨機線程獲取鎖,相率相對高。
new ReentrantLock(); //默認非公平鎖 new ReentrantLock(true); //公平鎖
“重入鎖(遞歸鎖)”與“不可重入鎖(自旋鎖)”
這里要注意了,重入/遞歸,不可重入/自旋,雖然名字不同,但是確實是同一種鎖,只是從鎖的表現跟實現方式的角度來命名而已。
重入鎖:當一個線程獲取了A鎖以后,若后續方法運行被A鎖鎖住的話,當前線程也是可以直接進入的。
public class Demo { private Lock lockA; public Demo(Lock Lock) { this.lockA = lock; } public void methodA() { lockA.lock(); methodB(); lockA.unlock(); } public void methodB() { lockA.lock(); //dosm lockA.unlock(); } }
當我們運行methodA()的時候,線程獲取了lockA,然后調用methodB()的時候發現也需要lockA,由于這是一個可重入鎖,所以當前線程也是可以直接進入的。在java中,synchronized跟ReetrantLock都是可重入鎖。
不可重入鎖:以上面的代碼實例來說明,就是methodA進入methodB的時候不能直接獲取鎖,必須先調用unLock釋放鎖。才能執行下去,那實現不可重入鎖有什么方式呢?那就是自旋,所以會有一個小名叫做自旋鎖。
public class SpinLock { private AtomicReference<Thread> sign =new AtomicReference<>(); public void lock(){ Thread current = Thread.currentThread(); while(!sign .compareAndSet(null, current)){ } } public void unlock (){ Thread current = Thread.currentThread(); sign .compareAndSet(current, null); } }
“悲觀鎖”與“樂觀鎖”
這兩種鎖呢,其實是一個很宏觀的分類,它不是一種具體的鎖,而是泛指看待并發的程度。
悲觀鎖:有一個“悲觀”的心態,既每次取數據的時候,都會認為該數據會被修改,所以必須加一把鎖才安心。
樂觀鎖:樂觀的孩子,認為同一個數據不會發生并發操作的行為,所以取的時候不會加鎖,只有在更新的時候,會通過例如版本號之類的來判斷是否數據被修改了。
Java中各種鎖其實都是悲觀鎖的實現,既操作的數據的都會被獲取鎖的線程鎖住,而樂觀鎖的話,一般是通過cas(compare and swap)的思想來實現,例如一些原子類AtomicInteger使用自旋來原子更新。
“共享鎖”與“排他鎖”
這兩種鎖的概念比較多的出現在數據庫的事務當中。
共享鎖:也稱讀鎖或S鎖。如果事務對數據A加上共享鎖后,則其他事務只能對A再加共享鎖,不能加排它鎖。獲準共享鎖的事務只能讀數據,不能修改數據。在java中的ReetrantReadWriteLock()也是如此。
排它鎖:也稱獨占鎖、寫鎖或X鎖。如果事務對數據A加上排它鎖后,則其他事務不能再對A加任何類型的鎖。獲得排它鎖的事務即能讀數據又能修改數據。
分布式鎖
我們上面聊的這些鎖,都是在單個程序上面的不同線程之間來實現的,那么當我們的不同程序需要去競爭同一塊資源的時候,這就需要分布式鎖了,我們可以通過redis、zookeeper等中間件來實現分布式鎖。
對于鎖來說,其實還有偏向鎖,輕量級鎖等,但是這里涉及到的內容就比較多,這里就不在展開篇幅介紹了,有興趣的同學可自行研究,如果你能搞懂上面介紹的這些鎖,那基本上在絕大部分的公司關于“鎖”的問題都可以迎刃而解。
感謝各位的閱讀!關于“java中各種鎖的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。