很久沒寫博文了,忙碌了一年多,在技術上走了好多彎路,還好因爲本身堅持不懈的努力終於從彎路中擺脫出來了,最近想回顧下關於java線程同步的知識,在這裏拋磚引玉,但願熱愛技術的程序猿們能一塊兒進步。java
說到java線程同步確定離不開synchronized,而關於synchronized這個關鍵字的細節,熱愛技術的朋友們是否真正掌握了呢?多線程
你們都知道,每一個java類都有一個繼承來自Object的對象鎖,也就是說new一個實例的同時虛擬機就賦予了這個實例的一個對象鎖,而且這個鎖是惟一的,那麼這個跟synchronized這個有什麼關係呢?關係大着呢,看如下代碼:測試
class Demo1 {
int index = 0;
public synchronized void getI() {
index=index+1;
}
public synchronized void setI() {
index=index-1;
}
}線程
class Demo2 {
int index = 0;
public synchronized void getI() {
index=index+1;
}
public void setI() {
index=index-1;
}
}對象
Demo1類裏面有兩個聲明瞭synchronized這個關鍵字的方法,Demo2裏面只有一個方法加了聲明,這二者的區別是什麼呢?(這裏有興趣的朋友能夠本身寫測試用例去觀察一下index變量的區別,這裏只把結論說出來)。若是你真正測試了,你就會發現Demo1的某個實例中在多線程環境下的某個時刻只能執行一個方法,而Demo2能夠同時執行,爲何呢?這裏面就有上面說到的對象鎖的概念了,一個synchronized關鍵字代表該對象鎖正在被佔用,一個聲明瞭synchronized關鍵字的方法只有拿到當前對象的對象鎖才能執行該方法。blog
以上只是單純的談了同步方法沒有談同步代碼塊,其實二者的區別主要就是做用域大小的關係,在這裏就很少坐解釋了。繼承
你們必定還想知道synchronized static與synchronized二者的區別吧,你們可能都知道static是類級別的關鍵字,已經超越了對象的概念了,那麼簡單點你們能夠理解爲類鎖,沒錯JDK有對象鎖的概念也有類鎖的概念呢。作用域
class Demo {
int index = 0;
public synchronized static void getI(Demo demo) {
demo.index=demo.index+1;
}
public synchronized void getI() {
index=index+1;
}
public synchronized void setI() {
index=index-1;
}
public synchronized static void setI(Demo demo) {
demo.index=demo.index-1;
}
}get
你們仔細看一下Demo類的四個方法兩個類方法,兩個對象方法,這個類主要想象你們說明什麼問題呢?其實很簡單就是想告訴你們類方法的同步方法與對象方法的同步方法佔用的不是同一個鎖,一個是類鎖,一個是對象鎖,所以他們不會出現互相搶佔鎖的狀況。
同步
本文出自 「陳硯羲」 博客,轉載請與做者聯繫!