新聞中心
Java虛擬機是如何執(zhí)行線程同步的
作者:Hollis譯 2017-11-14 16:43:13
開發(fā)
開發(fā)工具
虛擬化 想介紹下synchronized的原理,但是又不知道從何下手,在網上看到一篇老外的文章,介紹了和線程同步相關的幾個基礎知識點。所以想把它翻譯一下給大家看看。相信看過這些基礎知識之后再看我后面要寫的synchronized的原理就會好理解一點了。

成都創(chuàng)新互聯(lián)網站建設提供從項目策劃、軟件開發(fā),軟件安全維護、網站優(yōu)化(SEO)、網站分析、效果評估等整套的建站服務,主營業(yè)務為成都網站制作、網站建設,App定制開發(fā)以傳統(tǒng)方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。成都創(chuàng)新互聯(lián)深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
想介紹下synchronized的原理,但是又不知道從何下手,在網上看到一篇老外的文章,介紹了和線程同步相關的幾個基礎知識點。所以想把它翻譯一下給大家看看。相信看過這些基礎知識之后再看我后面要寫的synchronized的原理就會好理解一點了。
了解Java語言的人都知道,Java代碼要想被JVM執(zhí)行,需要被轉換成由字節(jié)碼組成的class文件。本文主要來分析下Java虛擬機是如何在字節(jié)碼層面上執(zhí)行線程同步的。
線程和共享數(shù)據
Java編程語言的優(yōu)點之一是它在語言層面上對多線程的支持。這種支持大部分集中在協(xié)調多個線程對共享數(shù)據的訪問上。JVM的內存結構主要包含以下幾個重要的區(qū)域:棧、堆、方法區(qū)等。
在Java虛擬中,每個線程獨享一塊棧內存,其中包括局部變量、線程調用的每個方法的參數(shù)和返回值。其他線程無法讀取到該棧內存塊中的數(shù)據。棧中的數(shù)據僅限于基本類型和對象引用。所以,在JVM中,棧上是無法保存真實的對象的,只能保存對象的引用。真正的對象要保存在堆中。
在JVM中,堆內存是所有線程共享的。堆中只包含對象,沒有其他東西。所以,堆上也無法保存基本類型和對象引用。堆和棧分工明確。但是,對象的引用其實也是對象的一部分。這里值得一提的是,數(shù)組是保存在堆上面的,即使是基本類型的數(shù)據,也是保存在堆中的。因為在Java中,數(shù)組是對象。
除了棧和堆,還有一部分數(shù)據可能保存在JVM中的方法區(qū)中,比如類的靜態(tài)變量。方法區(qū)和棧類似,其中只包含基本類型和對象應用。和棧不同的是,方法區(qū)中的靜態(tài)變量可以被所有線程訪問到。
對象和類的鎖
如前文提到,JVM中有兩塊內存區(qū)域可以被所有線程共享:
- 堆,上面存放著所有對象
- 方法區(qū),上面存放著靜態(tài)變量
那么,如果有多個線程想要同時訪問同一個對象或者靜態(tài)變量,就需要被管控,否則可能出現(xiàn)不可預期的結果。
為了協(xié)調多個線程之間的共享數(shù)據訪問,虛擬機給每個對象和類都分配了一個鎖。這個鎖就像一個特權,在同一時刻,只有一個線程可以“擁有”這個類或者對象。如果一個線程想要獲得某個類或者對象的鎖,需要詢問虛擬機。當一個線程向虛擬機申請某個類或者對象的鎖之后,也許很快或者也許很慢虛擬機可以把鎖分配給這個線程,同時這個線程也許永遠也無法獲得鎖。當線程不再需要鎖的時候,他再把鎖還給虛擬機。這時虛擬機就可以再把鎖分配給其他申請鎖的線程。
類鎖其實通過對象鎖實現(xiàn)的。因為當虛擬機加載一個類的時候,會會為這個類實例化一個 java.lang.Class 對象,當你鎖住一個類的時候,其實鎖住的是其對應的Class 對象。
監(jiān)視器(Monitors)
監(jiān)視器和鎖同時被JVM使用(我理解作者的意思應該是想說鎖其實是通過監(jiān)視器實現(xiàn)的。),監(jiān)視器主要功能是監(jiān)控一段代碼,確保在同一時間只有一個線程在執(zhí)行。
每個監(jiān)視器都與一個對象相關聯(lián)。當線程執(zhí)行到監(jiān)視器監(jiān)視下的代碼塊中的***條指令時,線程必須獲取對被引用對象的鎖定。在線程獲取鎖之前,他是無法執(zhí)行這段代碼的,一旦獲得鎖,線程便可以進入“被保護”的代碼開始執(zhí)行。
當線程離開代碼塊的時候,無論如何離開,都會釋放所關聯(lián)對象的鎖。
多次加鎖
同一個線程可以對同一個對象進行多次加鎖。每個對象維護著一個記錄著被鎖次數(shù)的計數(shù)器。未被鎖定的對象的該計數(shù)器為0,當一個線程獲得鎖后,該計數(shù)器自增變?yōu)?1 ,當同一個線程再次獲得該對象的鎖的時候,計數(shù)器再次自增。當同一個線程釋放鎖的時候,計數(shù)器再自減。當計數(shù)器為0的時候。鎖將被釋放,其他線程便可以獲得鎖。
同步
在Java中,當有多個線程都必須要對同一個共享數(shù)據進行訪問時,有一種協(xié)調方式叫做同步。Java語言提供了兩種內置方式來使線程同步的訪問數(shù)據:同步代碼塊和同步方法。
這篇文章中后面還介紹了同步代碼塊和同步方法,以及簡單的介紹了下實現(xiàn)方式。這里就不做翻譯了,因為我覺得他介紹的太簡單了。我后面專門寫篇文章詳細介紹。
原文地址:How the Java virtual machine performs thread synchronization
【本文是51CTO專欄作者Hollis的原創(chuàng)文章,作者微信公眾號Hollis(ID:hollischuang)】
戳這里,看該作者更多好文
分享題目:Java虛擬機是如何執(zhí)行線程同步的
新聞來源:http://www.dlmjj.cn/article/dpgedhs.html


咨詢
建站咨詢
