Java 多線程Synchronized和Lock的區(qū)別
引言
在多線程中,為了使線程安全,我們經(jīng)常會使用synchronized和Lock進行代碼同步和加鎖,但是具體兩者有什么區(qū)別,什么場景下適合用什么可能還不大清楚,主要的區(qū)別大致如下:
區(qū)別
1、synchronized是java關鍵字,而Lock是java中的一個接口
2、synchronized會自動釋放鎖,而Lock必須手動釋放鎖
3、synchronized是不可中斷的,Lock可以中斷也可以不中斷
4、通過Lock可以知道線程有沒有拿到鎖,而synchronized不能
5、synchronized能鎖住方法和代碼塊,而Lock只能鎖住代碼塊
6、Lock可以使用讀鎖提高多線程讀效率
7、synchronized是非公平鎖,ReentranLock可以控制是否公平鎖
從Lock接口中我們可以看到主要有5個方法,這些方法的功能從注釋中可以看出:
lock():獲取鎖,如果鎖被暫用則一直等待 unlock():釋放鎖 tryLock(): 注意返回類型是boolean,如果獲取鎖的時候鎖被占用就返回false,否則返回true tryLock(long time, TimeUnit unit):比起tryLock()就是給了一個時間期限,保證等待參數(shù)時間 lockInterruptibly():用該鎖的獲得方式,如果線程在獲取鎖的階段進入了等待,那么可以中斷此線程,先去做別的事 通過 以上的解釋,大致可以解釋在上個部分中“鎖類型(lockInterruptibly())”,“鎖狀態(tài)(tryLock())”等問題,還有就是前面子所獲取的過程我所寫的“大致就是可以嘗試獲得鎖,線程可以不會一直等待”用了“可以”的原因。
lock():
public class LockTest { private Lock lock = new ReentrantLock(); private void method(Thread thread) { lock.lock(); try { System.out.println(thread.getName() + " has gotten the lock!"); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println(thread.getName() + " has unlocked the lock!"); lock.unlock(); } } public static void main(String[] args) { final LockTest test = new LockTest(); Thread t1 = new Thread(new Runnable() { @Override public void run() { test.method(Thread.currentThread()); } }, "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { test.method(Thread.currentThread()); } }, "t2"); t1.start(); t2.start(); } }
運行結(jié)果:
t1 has gotten the lock! t1 has unlocked the lock! t2 has gotten the lock! t2 has unlocked the lock!
tryLock():
public class LockTest { private Lock lock = new ReentrantLock(); private void method(Thread thread) { if (lock.tryLock()) { lock.lock(); try { System.out.println(thread.getName() + " has gotten the lock!"); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println(thread.getName() + " has unlocked the lock!"); lock.unlock(); } } else { System.out.println("I'm "+thread.getName()+". Someone has gotten the lock!"); } } public static void main(String[] args) { LockTest test = new LockTest(); Thread t1 = new Thread(() -> test.method(Thread.currentThread()), "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { test.method(Thread.currentThread()); } }, "t2"); t1.start(); t2.start(); } }
運行結(jié)果:
t1 has gotten the lock! t1 has unlocked the lock! I'm t2. Someone has gotten the lock!
看到這里相信大家也都會使用如何使用Lock了吧,關于tryLock(long time, TimeUnit unit)和lockInterruptibly()不再贅述。前者主要存在一個等待時間,在測試代碼中寫入一個等待時間,后者主要是等待中斷,會拋出一個中斷異常,常用度不高,喜歡探究可以自己深入研究。
以上就是Java 多線程Synchronized和Lock的區(qū)別的詳細內(nèi)容,更多關于Java 多線程Synchronized和Lock的資料請關注腳本之家其它相關文章!
- 深入Synchronized和java.util.concurrent.locks.Lock的區(qū)別詳解
- 詳談Lock與synchronized 的區(qū)別
- Java編程synchronized與lock的區(qū)別【推薦】
- 簡單了解synchronized和lock的區(qū)別
- 淺談Synchronized和Lock的區(qū)別
- 通過實例解析synchronized和lock區(qū)別
- 淺談Java中Lock和Synchronized的區(qū)別
- Java常用鎖synchronized和ReentrantLock的區(qū)別
- synchronized?和?Lock?的異同點(如何讓選擇)
相關文章
SpringBoot實現(xiàn)各種參數(shù)校驗總結(jié)(建議收藏!)
本文深入解析了Spring?Validation的使用方法、實現(xiàn)原理及最佳實踐,詳細介紹了各種參數(shù)校驗場景,如requestBody和requestParam/PathVariable的使用,并探討了分組校驗、嵌套校驗和自定義校驗的高級應用,需要的朋友可以參考下2024-09-09Spring?Boot源碼實現(xiàn)StopWatch優(yōu)雅統(tǒng)計耗時
這篇文章主要為大家介紹了Spring?Boot源碼實現(xiàn)StopWatch優(yōu)雅統(tǒng)計耗時,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07詳解Eclipse Validating緩慢的優(yōu)化
這篇文章主要介紹了詳解Eclipse Validating緩慢的優(yōu)化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03詳解SpringBoot如何使用JWT實現(xiàn)身份認證和授權
JSON?Web?Token(JWT)是一種用于在網(wǎng)絡應用之間安全傳遞信息的開放標準,本文主要為大家介紹了如何在Spring?Boot中使用JWT實現(xiàn)身份認證和授權,需要的可以了解下2023-10-10基于Failed?to?load?ApplicationContext異常的解決思路
這篇文章主要介紹了基于Failed?to?load?ApplicationContext異常的解決思路,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01