java線程中synchronized和Lock區(qū)別及介紹
synchronized 介紹與使用
synchronized 和 Lock 都是 Java 中用于實(shí)現(xiàn)線程同步的機(jī)制,它們都可以保證線程安全。
synchronized 可用來修飾普通方法、靜態(tài)方法和代碼塊,當(dāng)一個(gè)線程訪問一個(gè)被 synchronized 修飾的方法或者代碼塊時(shí),會(huì)自動(dòng)獲取該對(duì)象的鎖,其他線程將會(huì)被阻塞,直到該線程執(zhí)行完畢并釋放鎖。這樣就保證了多個(gè)線程對(duì)共享資源的操作的互斥性,從而避免了數(shù)據(jù)的不一致性和線程安全問題。
synchronized 基本使用如下:
public class SynchronizedDemo { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }
此時(shí)我們?cè)偈褂枚嗑€程調(diào)用上面類的 increment 或 getCount 時(shí),就不會(huì)出現(xiàn)線程安全問題了,如下代碼所示:
public class SynchronizedDemoTest { public static void main(String[] args) { SynchronizedDemo demo = new SynchronizedDemo(); Runnable r = () -> { for (int i = 0; i < 1000; i++) { demo.increment(); } }; Thread t1 = new Thread(r); Thread t2 = new Thread(r); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Count: " + demo.getCount()); } }
Lock 介紹與使用
Lock 是一種線程同步的機(jī)制,它與 synchronized 相似,可以用于控制對(duì)共享資源的訪問。相比于 synchronized,Lock 的特點(diǎn)在于更加靈活,支持更多的操作。
Lock 接口定義了以下方法:
- lock():獲取鎖,如果鎖已被其他線程占用,則阻塞當(dāng)前線程。
- tryLock():嘗試獲取鎖,如果鎖已被其他線程占用,則返回 false,否則返回 true。
- tryLock(long timeout, TimeUnit unit):嘗試獲取鎖,在指定的時(shí)間范圍內(nèi)獲取到鎖則返回 true,否則返回 false。
- unlock():釋放鎖。
相比于 synchronized,Lock 的優(yōu)點(diǎn)在于:
- 粒度更細(xì):synchronized 關(guān)鍵字只能對(duì)整個(gè)方法或代碼塊進(jìn)行同步,而 Lock 可以對(duì)單個(gè)變量或?qū)ο筮M(jìn)行同步。
- 支持公平鎖:synchronized 不支持公平鎖,而 Lock 可以通過構(gòu)造函數(shù)指定鎖是否是公平鎖。
- 支持多個(gè)條件變量:Lock 可以創(chuàng)建多個(gè)條件變量,即多個(gè)等待隊(duì)列。
Lock 的實(shí)現(xiàn)類有很多,比較常用的有 ReentrantLock 和 ReentrantReadWriteLock。
需要注意的是,使用 Lock 時(shí)需要手動(dòng)獲取和釋放鎖,否則會(huì)導(dǎo)致死鎖等問題。因此,一般來說建議使用 try-finally 語句塊來確保鎖的正確釋放。例如:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Counter { private int count = 0; private Lock lock = new ReentrantLock(); public void increment() { // 加鎖 lock.lock(); try { count++; } finally { // 釋放鎖 lock.unlock(); } } public void decrement() { // 加鎖 lock.lock(); try { count--; } finally { // 釋放鎖 lock.unlock(); } } public int getCount() { return count; } }
synchronized VS Lock
synchronized 和 Lock 主要的區(qū)別有以下幾個(gè)方面:
- 鎖的獲取方式:synchronized 是隱式獲取鎖的,即在進(jìn)入 synchronized 代碼塊或方法時(shí)自動(dòng)獲取鎖,退出時(shí)自動(dòng)釋放鎖;而 Lock 需要程序顯式地獲取鎖和釋放鎖,即需要調(diào)用 lock() 方法獲取鎖,調(diào)用 unlock() 方法釋放鎖。
- 鎖的性質(zhì):synchronized 是可重入的互斥鎖,即同一個(gè)線程可以多次獲得同一把鎖,而且鎖的釋放也只能由獲得鎖的線程來釋放;Lock 可以是可重入的互斥鎖,也可以是非可重入的互斥鎖,還可以是讀寫鎖。
- 鎖的粒度:synchronized 是以代碼塊和方法為單位進(jìn)行加鎖和解鎖,而 Lock 可以精確地控制鎖的范圍,可以支持多個(gè)條件變量。
- 性能:在低并發(fā)的情況下,synchronized 的性能優(yōu)于 Lock,因?yàn)?Lock 需要顯式地獲取和釋放鎖,而 synchronized 是在 JVM 層面實(shí)現(xiàn)的;在高并發(fā)的情況下,Lock 的性能可能優(yōu)于 synchronized,因?yàn)?Lock 可以更好地支持高并發(fā)和讀寫分離的場(chǎng)景。
總的來說,synchronized 的使用更加簡(jiǎn)單,但是在某些場(chǎng)景下會(huì)受到性能的限制;而 Lock 則更加靈活,可以更精確地控制鎖的范圍和條件變量,但是使用起來比較繁瑣。需要根據(jù)具體的業(yè)務(wù)場(chǎng)景和性能需求來選擇使用哪種鎖機(jī)制。
以上就是java線程中synchronized和Lock區(qū)別及介紹的詳細(xì)內(nèi)容,更多關(guān)于java線程synchronized Lock的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
eclipse老是自動(dòng)跳到console解決辦法
eclipse啟動(dòng)服務(wù)后,想看一些properties信息或者別的,但老是自動(dòng)跳轉(zhuǎn)到console頁面,本文給大家介紹了解決辦法,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03IDEA 2020.1打開時(shí)閃退的問題及解決方法(完美解決方法)
這篇文章主要介紹了IDEA 2020.1打開時(shí)閃退問題及解決方法,本文給大家分享我的處理方案,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Spring事務(wù)中@Transactional注解不生效的原因分析與解決
在Spring框架中,@Transactional注解是管理數(shù)據(jù)庫(kù)事務(wù)的核心方式,本文將深入分析事務(wù)自調(diào)用的底層原理,解釋為什么事務(wù)不生效,并提供多種解決方案,希望對(duì)大家有所幫助2025-03-03Java中實(shí)現(xiàn)分布式定時(shí)任務(wù)的方法
這篇文章主要介紹了Java中實(shí)現(xiàn)分布式定時(shí)任務(wù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Spring Boot中自動(dòng)執(zhí)行sql腳本的實(shí)現(xiàn)
這篇文章主要介紹了Spring Boot中自動(dòng)執(zhí)行sql腳本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12mybatis實(shí)現(xiàn)增刪改查_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
本文通過實(shí)例代碼給大家介紹了mybatis實(shí)現(xiàn)增刪改查功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-09-09