日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

并发编程之Synchronized原理

發布時間:2025/4/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 并发编程之Synchronized原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、基本使用

? ?1.Synchronized的作用。

  • 原子性:確保線程互斥的訪問同步代碼;
  • 可見性:保證共享變量的修改能夠及時可見,其實是通過Java內存模型中的 “對一個變量unlock操作之前,必須要同步到主內存中;如果對一個變量進行lock操作,則將會清空工作內存中此變量的值,在執行引擎使用此變量前,需要重新從主內存中load操作或assign操作初始化變量值” 來保證的;
  • 有序性:有效解決重排序問題,即 “一個unlock操作先行發生(happen-before)于后面對同一個鎖的lock操作”
???2.Synchronized的三種用法。Synchronized可以把任何一個非null對象作為"鎖"。
  • 當synchronized作用在實例方法時,監視器鎖(monitor)便是對象實例(this)
  • 當synchronized作用在靜態方法時,監視器鎖(monitor)便是對象的Class實例,因為Class數據存在于永久代,因此靜態方法鎖相當于該類的一個全局鎖
  • 當synchronized作用在某一個對象實例時,監視器鎖(monitor)便是括號括起來的對象實例。

? 3.synchronized與Lock的區別

? 1.首先synchronized是java內置關鍵字,在jvm層面,Lock是個java類;

? 2.synchronized無法判斷是否獲取鎖的狀態,Lock可以判斷是否獲取到鎖;

? 3.synchronized會自動釋放鎖(a?線程執行完同步代碼會釋放鎖 ;b 線程執行過程中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),否則容易造成線程死鎖;

? 4.用synchronized關鍵字的兩個線程1和線程2,如果當前線程1獲得鎖,線程2線程等待。如果線程1阻塞,線程2則會一直等待下去,而Lock鎖就不一定會等待下去,如果嘗試獲取不到鎖,線程可以不用一直等待就結束了;

? 5.synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(兩者皆可)

? 6.Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少量的同步問題。

類別synchronizedLock
存在層次Java的關鍵字,在jvm層面上是一個類
鎖的釋放1、以獲取鎖的線程執行完同步代碼,釋放鎖 2、線程執行發生異常,jvm會讓線程釋放鎖在finally中必須釋放鎖,不然容易造成線程死鎖
鎖的獲取假設A線程獲得鎖,B線程等待。如果A線程阻塞,B線程會一直等待分情況而定,Lock有多個鎖獲取的方式,具體下面會說道,大致就是可以嘗試獲得鎖,線程可以不用一直等待
鎖狀態無法判斷可以判斷
鎖類型可重入 不可中斷 非公平可重入 可判斷 可公平(兩者皆可)
性能少量同步大量同步
二、同步原理

1.數據同步需要依賴鎖,那鎖的同步又依賴誰?

?synchronized:在軟件層面依賴JVM。

?j.u.c.Lock:在硬件層面依賴特殊的CPU指令。

2.監視器鎖(monitor):每個對象都是一個監視器鎖(monitor)。

??Synchronized的語義底層是通過一個monitor的對象來完成。

3.monitorenter:每個對象都是一個監視器鎖(monitor)。當monitor被占用時就會處于鎖定狀態,線程執行monitorenter指令時嘗試獲取monitor的所有權。

  • 如果monitor的進入數為0,則該線程進入monitor,然后將進入數設置為1,該線程即為monitor的所有者;
  • 如果線程已經占有該monitor,只是重新進入,則進入monitor的進入數加1;
  • 如果其他線程已經占用了monitor,則該線程進入阻塞狀態,直到monitor的進入數為0,再重新嘗試獲取monitor的所有權;

4.monitorexit:執行monitorexit的線程必須是objectref所對應的monitor的所有者。指令執行時,monitor的進入數減1,如果減1后進入數為0,那線程退出monitor,不再是這個monitor的所有者。其他被這個monitor阻塞的線程可以嘗試去獲取這個 monitor 的所有權。

三、同步概念

1.Java對象頭

? 對象在內存中的布局分為三塊區域:對象頭、實例數據和對齊填充。

  • 實例數據:存放類的屬性數據信息,包括父類的屬性信息;
  • 對齊填充:由于虛擬機要求 對象起始地址必須是8字節的整數倍。填充數據不是必須存在的,僅僅是為了字節對齊;
  • 對象頭Java對象頭一般占有2個機器碼(在32位虛擬機中,1個機器碼等于4字節,也就是32bit,在64位虛擬機中,1個機器碼是8個字節,也就是64bit),但是 如果對象是數組類型,則需要3個機器碼,因為JVM虛擬機可以通過Java對象的元數據信息確定Java對象的大小,但是無法從數組的元數據來確認數組的大小,所以用一塊來記錄數組長度。

??

?2.對象頭中Mark Word與線程中Lock Record

?3.監視器(Monitor)

?任何一個對象都有一個Monitor與之關聯,當且一個Monitor被持有后,它將處于鎖定狀態。

?Synchronized在JVM里的實現都是?基于進入和退出Monitor對象來實現方法同步和代碼塊同步。

?3.1?MonitorEnter指令:插入在同步代碼塊的開始位置,當代碼執行到該指令時,將會嘗試獲取該對象Monitor的所有權,即嘗試獲得該對象的鎖;

?3.2 MonitorExit指令:插入在方法結束處和異常處,JVM保證每個MonitorEnter必須有對應的MonitorExit;

?參考:深入分析Synchronized原理。

?

轉載于:https://www.cnblogs.com/wenxiangchen/p/11340799.html

總結

以上是生活随笔為你收集整理的并发编程之Synchronized原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。