synchronized 和Lock區別

synchronized實現原理

Java中每一個對象都可以作為鎖,這是synchronized實現同步的基礎:

  1. 普通同步方法,鎖是當前實例對象
  2. 靜態同步方法,鎖是當前類的class對象
  3. 同步方法塊,鎖是括號里面的對象
    當一個線程訪問同步代碼塊時,它首先是需要得到鎖,當退出或者拋出異常時必須要釋放鎖,那么它是如何來實現這個機制的呢?我們先看一段簡單的代碼:
package cn.alibab.javap;public class SynchronizedTest {public synchronized void test1(){}public void test2(){synchronized (this){}}
}
  • ?

利用javap工具(javap是java編譯之后的class文件的分解器)查看生成的class文件信息來分析Synchronized的實現

這里寫圖片描述

這里寫圖片描述
從上面可以看出,同步代碼塊是使用monitorenter和monitorexit指令實現的,同步方法(在這看不出來需要看JVM底層實現)依靠的是方法修飾符上的ACC_SYNCHRONIZED實現。

同步代碼塊:monitorenter指令是在編譯后插入到同步代碼塊的開始位置,monitorexit指令插入到同步代碼塊的結束位置,JVM需要保證每一個monitorenter都有一個monitorexit與之相對應。任何對象都有一個monitor與之相關聯,當且一個monitor被持有之后,他將處于鎖定狀態。線程執行到monitorenter指令時,將會嘗試獲取對象所對應的monitor所有權,即嘗試獲取對象的鎖;【摘自并發編程藝術】

同步方法:synchronized方法則會被翻譯成普通的方法調用和返回指令如:invokevirtual、areturn指令,在VM字節碼層面并沒有任何特別的指令來實現被synchronized修飾的方法,而是在Class文件的方法表中將該方法的access_flags字段中的synchronized標志位置1,表示該方法是同步方法并使用調用該方法的對象或該方法所屬的Class在JVM的內部對象表示Klass做為鎖對象。(摘自:http://www.cnblogs.com/javaminer/p/3889023.html)

synchronized和lock的區別

這里寫圖片描述
區別如下:

  1. 來源:
    lock是一個接口,而synchronized是java的一個關鍵字,synchronized是內置的語言實現;

  2. 異常是否釋放鎖:
    synchronized在發生異常時候會自動釋放占有的鎖,因此不會出現死鎖;而lock發生異常時候,不會主動釋放占有的鎖,必須手動unlock來釋放鎖,可能引起死鎖的發生。(所以最好將同步代碼塊用try catch包起來,finally中寫入unlock,避免死鎖的發生。)

  3. 是否響應中斷
    lock等待鎖過程中可以用interrupt來中斷等待,而synchronized只能等待鎖的釋放,不能響應中斷;

  4. 是否知道獲取鎖
    Lock可以通過trylock來知道有沒有獲取鎖,而synchronized不能;

  5. Lock可以提高多個線程進行讀操作的效率。(可以通過readwritelock實現讀寫分離)

  6. 在性能上來說,如果競爭資源不激烈,兩者的性能是差不多的,而當競爭資源非常激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優于synchronized。所以說,在具體使用時要根據適當情況選擇。

  7. synchronized使用Object對象本身的wait 、notify、notifyAll調度機制,而Lock可以使用Condition進行線程之間的調度,

//Condition定義了等待/通知兩種類型的方法
Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();
...
condition.await();
...
condition.signal();
condition.signalAll();
  • ?

1、synchronized和lock的用法區別

synchronized:在需要同步的對象中加入此控制,synchronized可以加在方法上,也可以加在特定代碼塊中,括號中表示需要鎖的對象。

lock:一般使用ReentrantLock類做為鎖。在加鎖和解鎖處需要通過lock()和unlock()顯示指出。所以一般會在finally塊中寫unlock()以防死鎖。

2、synchronized和lock性能區別

synchronized是托管給JVM執行的,
而lock是java寫的控制鎖的代碼。

在Java1.5中,synchronize是性能低效的。因為這是一個重量級操作,需要調用操作接口,導致有可能加鎖消耗的系統時間比加鎖以外的操作還多。相比之下使用Java提供的Lock對象,性能更高一些。

但是到了Java1.6,發生了變化。synchronize在語義上很清晰,可以進行很多優化,有適應自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他們也更支持synchronize,在未來的版本中還有優化余地。

2種機制的具體區別:
synchronized原始采用的是CPU悲觀鎖機制,即線程獲得的是獨占鎖。獨占鎖意味著其他線程只能依靠阻塞來等待線程釋放鎖。而在CPU轉換線程阻塞時會引起線程上下文切換,當有很多線程競爭鎖的時候,會引起CPU頻繁的上下文切換導致效率很低。

而Lock用的是樂觀鎖方式。所謂樂觀鎖就是,每次不加鎖而是假設沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功為止。樂觀鎖實現的機制就是CAS操作(Compare and Swap)。我們可以進一步研究ReentrantLock的源代碼,會發現其中比較重要的獲得鎖的一個方法是compareAndSetState。這里其實就是調用的CPU提供的特殊指令。

現代的CPU提供了指令,可以自動更新共享數據,而且能夠檢測到其他線程的干擾,而 compareAndSet() 就用這些代替了鎖定。這個算法稱作非阻塞算法,意思是一個線程的失敗或者掛起不應該影響其他線程的失敗或掛起的算法。

3、synchronized和lock用途區別

synchronized原語和ReentrantLock在一般情況下沒有什么區別,但是在非常復雜的同步應用中,請考慮使用ReentrantLock,特別是遇到下面2種需求的時候。

1.某個線程在等待一個鎖的控制權的這段時間需要中斷
2.需要分開處理一些wait-notify,ReentrantLock里面的Condition應用,能夠控制notify哪個線程
3.具有公平鎖功能,每個到來的線程都將排隊等候

下面細細道來……

先說第一種情況,ReentrantLock的lock機制有2種,忽略中斷鎖和響應中斷鎖,這給我們帶來了很大的靈活性。比如:如果A、B 2個線程去競爭鎖,A線程得到了鎖,B線程等待,但是A線程這個時候實在有太多事情要處理,就是一直不返回,B線程可能就會等不及了,想中斷自己,不再等待這個鎖了,轉而處理其他事情。這個時候ReentrantLock就提供了2種機制:可中斷/可不中斷
第一,B線程中斷自己(或者別的線程中斷它),但是ReentrantLock不去響應,繼續讓B線程等待,你再怎么中斷,我全當耳邊風(synchronized原語就是如此);
第二,B線程中斷自己(或者別的線程中斷它),ReentrantLock處理了這個中斷,并且不再等待這個鎖的到來,完全放棄。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/386517.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386517.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386517.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

美團安卓面試,難道Android真的涼了?快來收藏!

我所接觸的Android開發者,百分之九十五以上 都遇到了以下幾點致命弱點! 如果這些問題也是阻止你升職加薪,跳槽大廠的阻礙。 那么我確信可以幫你突破瓶頸! 1.開發者的門越來越高: 小廠的機會少了,大廠…

django -- 實現ORM登錄

前戲 上篇文章寫了一個簡單的登錄頁面,那我們可不可以實現一個簡單的登錄功能呢?如果登錄成功,給返回一個頁面,失敗給出錯誤的提示呢? 在之前學HTML的時候,我們知道,網頁在往服務器提交數據的時…

美團點評APP在移動網絡性能優化的實踐,通用流行框架大全

" 對于程序員來說,如果哪一天開始他停止了學習,那么他的職業生涯便開始宣告消亡。” 高薪的IT行業是眾多年輕人的職業夢想,然而,一旦身入其中卻發覺沒有想像中那么美好。被稱為IT藍領的編程員,工作強度大&#xf…

java 8大happen-before原則超全面詳解

再來重復下八大原則: 單線程happen-before原則:在同一個線程中,書寫在前面的操作happen-before后面的操作。鎖的happen-before原則:同一個鎖的unlock操作happen-before此鎖的lock操作。volatile的happen-before原則:對…

centos7.0利用yum快速安裝mysql8.0

我這里直接使用MySQL Yum存儲庫的方式快速安裝: 抽象 MySQL Yum存儲庫提供用于在Linux平臺上安裝MySQL服務器,客戶端和其他組件的RPM包。這些軟件包還可以升級和替換從Linux發行版本機軟件存儲庫安裝的任何第三方MySQL軟件包,如果可以從MySQL…

騰訊3輪面試都問了Android事件分發,論程序員成長的正確姿勢

前言 這些題目是網友去美團等一線互聯網公司面試被問到的題目。筆者從自身面試經歷、各大網絡社交技術平臺搜集整理而成,熟悉本文中列出的知識點會大大增加通過前兩輪技術面試的幾率。 主要分為以下幾部分: (1)Android面試題 …

happens-before規則和as-if-serial語義

概述 本文大部分整理自《Java并發編程的藝術》,溫故而知新,加深對基礎的理解程度。 指令序列的重排序 我們在編寫代碼的時候,通常自上而下編寫,那么希望執行的順序,理論上也是逐步串行執行,但是為了提高…

安裝nodejs

1.安裝nodejs:node-v8.12.0-x64.msi; 2.檢測是否安裝成功: 3.地址欄打開命令行:輸入 cmd回車 4.檢測node是否安裝成功:node -v 看到版本號就是安裝成功了 5.檢測npm是否成功:npm -v 是安裝成功了 6、如果npm成功了,把 package.js…

貼片晶振無源石英諧振器直插晶振

貼片晶振 貼片晶振3.579M~25MHz無源石英諧振器直插晶振 文章目錄 貼片晶振前言一、貼片晶振3.579M~25MHz無源石英諧振器直插晶振二、屬性三、技術參數總結前言 貼片晶振(Surface Mount Crystal Oscillator)是一種采用表面貼裝技術進行安裝的晶振。它的主要特點是封裝小巧、安…

這些新技術你們都知道嗎?成功收獲美團,小米安卓offer

前言 近期被兩則消息刷屏,【字節跳動持續大規模招聘,全年校招超過1萬人】【騰訊有史以來最大規模的校招啟動】當然Android崗位也包含在內,因此Android還是有很多機會的。結合往期面試的同學(主要是校招)經驗&#xff…

CompareAndSwap原子操作原理

在翻閱AQS(AbstractQueuedSynchronizer)類的過程中,發現其進行原子操作的時候采用的是CAS。涉及的代碼如下: 1: private static final Unsafe unsafe Unsafe.getUnsafe(); 2: private static final long stateOffset; 3: private static f…

STemWin移植筆記

實現將STemWin圖形庫移植到STM32F103ZET中,記錄簡單的操作步驟,以便自己后續查閱。 1/ 從官網獲取STemWin庫的壓縮包en.stemwin.zip。 2/ 解壓后,在路徑STemWin_Library_V1.2.0\Libraries\STemWinLibrary532下可以找到庫文件。 3/ 移植前的準…

這些新技術你們都知道嗎?看這一篇就夠了!

前言 現在已經進入招聘季節,本篇文章旨在分享知名互聯網企業面試官面試方法和心得,希望通過本文的閱讀能給程序員帶來不一樣的面試體驗和感受,放松面試心態,積極備戰! 面試題 PS:由于文章篇幅問題&#x…

spring boot redis 分布式鎖

yml文件 redis:host: 127.0.0.1port: 40197password: 123456timeout: 5000database: 0jedis:pool:min-idle: 0max-idle: 8max-active: 8max-wait: -1 RedisConfig.java import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer…

mysql函數(二.數字函數)

數字函數 1.ROUND(X) 四舍五入取整數 ROUND(X,D) 四舍五入根據D幾,來保留幾位小數 (1)四舍五入取整數 select ROUND(1.567); 結果:2 (2)四舍五入根據D2,來保留2位小數 select ROUND(1.567,2)DESC; 結果:1.57 2.CEIL…

這份1307頁Android面試全套真題解析,源碼+原理+手寫框架

前言 前不久,幾個朋友聚會,談到了現在的后輩,我就說起了那個大三就已經拿到網易offer的小學弟。 這個學弟是00后,專升本進入我們學校的。進來后就非常努力,每次上課都是第一個到教室的,每次都是坐第一排&…

CAS的ABA問題描述 AtomicStampReference

CAS的ABA問題描述 在CAS操作的時候,其他線程將當前變量的值從A改成B,又改回A;CAS線程用期望值A與當前變量比較的時候,發現當前變量沒有變,于是CAS就將當前變量進行了交換操作,但其實當前變量改變過&#x…

[轉]OpenContrail 體系架構文檔

OpenContrail 體系架構文檔英文原文:http://opencontrail.org/opencontrail-architecture-documentation/ 翻譯者:KkBLuE知行合一 其微信號:kkbluepublic, SDNAP.com翻譯整理 OpenContrail 體系架構文檔 1 概述 1.1 使用案例 1…

這份354頁筆記的Android進階知識+大廠高頻面試題,絕對干貨

程序員與別的專業有所不同,其他專業都是越老越香,而程序員卻是一個例外,因為計算機技術更新太快,而且工作強度很大,因此大部分程序員只會寫 3 年代碼。3 年后要不晉升做項目經理,要么轉行,個別研…

原子性 atomic 類用法

當程序更新一個變量時,如果多線程同時更新這個變量,可能得到期望之外的值,比如變量i1,A線程更新i1,B線程也更新i1,經過兩個線程操作之后可能i不等于3,而是等于2。因為A和B線程在更新變量i的時候…