synchronized

1.synchronized是利用鎖的機制來實現同步的

鎖機制有如下兩個特徵:

互斥性:在同一時間只允許一個線程持有某個對象鎖,通過這種特性來實現多線程中的協調機制,這樣在同一時間只有一個線程對同步代碼塊進行訪問。互斥性我們往往也叫操作的原子性。

可見性:必須確保在鎖被釋放之前,對共享變量做的修改,對隨後獲得該鎖的另一個線程是可見的(即在獲得鎖時,應獲得最新共享變量的值),否則另一個線程可能是在本地緩存的某個副本上繼續操作,從而導致不一致。

2.根據獲取的鎖分類

1.獲取對象鎖

synchronized(this|object):修飾非靜態方法,在java中,每一個對象都會有一個monitor對象,這個對象其實就是java對象的鎖,通常被稱爲內置鎖或者對象鎖。類的對象可以有多個,所以每個對象有其獨立的對象鎖,互不干擾。

2.獲取類鎖

synchronized(類.class):修飾靜態方法,在java中,針對每一個類也有一個鎖,可以稱爲類鎖,類鎖實際上是通過對象鎖實現的,即類的Class對象鎖。每一個類只有一個Class對象鎖,所以每一個類只有一個鎖。

 

3.在java中,每一個對象都會有一個monitor對象,即監視器

某一線程佔有這個對象的時候,先monitor 的計數器是不是0,如果是0還沒有線程佔有,這個時候線程佔有這個對象,並且對這個對象的monitor+1;如果不爲0,表示這個對象已經被其他線程佔有,這個線程等待。當線程釋放佔有權的時候,monitor-1;同一線程可以對同一對象進行多次加鎖,+1,+1,重入性

3.synchronized的原理分析

我們下面來看下一個簡答的多線程實現買票的例子

看下反編譯下的字節碼文件(看不懂字節碼的朋友可以關注我,我很快就會推出來字節碼的博客,請耐心等待):

進入到這個類的class文件的位置

javap -v TicketDemo.class

Monitor

(1)0,lock

  1. 重入
  2. monitor一個線程佔有,其他線程請求時會進入BOLCK,直到monitor爲0

Monitorexit

  計數器減一,爲0時爲解鎖

4.使用synchronized注意的問題

  1. 與moniter關聯的對象不能爲空
  2. synchronized作用域太大
  3. 不同的monitor企圖鎖相同的方法
  4. 多個鎖的交叉導致死鎖

 

5.java虛擬機對synchronized的優化

對象頭與monitor

一個對象實例包含:對象頭(j加鎖的基礎)、實例變量、填充數據

無鎖狀態:沒有加鎖

偏向鎖:在對象第一次被某一線程佔有的時候,是否偏向鎖置1,鎖表01,寫入線程號,當其他的線 程訪問的時候,競爭,失敗  輕量級鎖

    多次悲第一次佔有它的線程獲取次數多,成功 

CAS算法 campany and setCAS)(之前的博客已經講述過)

無鎖狀態時間非常接近

競爭不激烈的時候適用

輕量級鎖:線程有交替適用,互斥性不是很強,CAS失敗,00

重量級鎖:強互斥,10,等待時間長

自旋鎖:競爭失敗的時候,不是馬上轉化級別,而是執行幾次空循環5 10

鎖消除:JIT在編譯的時候吧不必要的鎖去掉

 

// TODO 剩下的以後在接着補充,今天先到這

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章