java - 一個(gè)類的對(duì)象鎖只有一個(gè),類鎖呢?
問題描述
一個(gè)類的對(duì)象鎖只有一個(gè),如果有幾個(gè)非靜態(tài)函數(shù)都是synchronized,在某一時(shí)刻只有一個(gè)線程能調(diào)用其中一個(gè)函數(shù)
假如一個(gè)類有幾個(gè)靜態(tài)函數(shù)是synchronized,在某一時(shí)刻只有一個(gè)線程能調(diào)用其中一個(gè)靜態(tài)函數(shù)嗎?也就是類鎖也只有一個(gè)嗎?
問題解答
回答1:前面一種鎖的是實(shí)例對(duì)象,鎖定了當(dāng)前的那個(gè)對(duì)象,如果有多個(gè)實(shí)例對(duì)象,這些synchronized方法之間不是同步的。第二種鎖的是類對(duì)象,類對(duì)象就一個(gè),所以是同步的。
回答2:public class Foo { synchronized void test1() {//to implements } void test2() {synchronized(this) { //to implements} } synchronized static void test3() {//to implements } static void test4() {synchronized(Foo.class) { //to implements} }}
如上代碼,test1方法相當(dāng)于test2,當(dāng)this是同一個(gè)對(duì)象時(shí),會(huì)發(fā)生阻塞。當(dāng)然,不同對(duì)象沒有關(guān)系,因?yàn)閠his不一樣。稱為對(duì)象級(jí)鎖。test3相當(dāng)于test4,這里是用class對(duì)象作為鎖,因?yàn)橐话闱闆r下一個(gè)類的類實(shí)例只有一個(gè),那么每次進(jìn)入這個(gè)方法都會(huì)鎖。稱為類級(jí)鎖。
回答3:非靜態(tài)同步方法(A)用的鎖就是當(dāng)前實(shí)例對(duì)象本身,一個(gè)實(shí)例的A獲取鎖之后,該實(shí)例的其他A必須等待鎖的釋放,多個(gè)實(shí)例用的都是不同的鎖;
靜態(tài)同步方法(B)用的鎖是類對(duì)象本身,一旦一個(gè)B獲取鎖之后其他的B都必須等待釋放鎖,不管是一個(gè)實(shí)例還是多個(gè)實(shí)例;
另外 A和B之間用不同的鎖,所以不會(huì)有競(jìng)爭(zhēng)關(guān)系;
回答4:Class類創(chuàng)建一個(gè)對(duì)象就是代表一個(gè)普通類,這時(shí)“類鎖”就是這個(gè)實(shí)例對(duì)象上的鎖
回答5:你說的是“互斥鎖”的概念,針對(duì)synchronized修飾方法有兩種情況:
【非靜態(tài)方法】
當(dāng)一個(gè)方法被synchronized修飾后,鎖對(duì)象為當(dāng)前方法所屬對(duì)象,即方法中的this。
【靜態(tài)方法】
當(dāng)一個(gè)靜態(tài)方法被synchronized修飾后,該靜態(tài)方法上鎖的對(duì)象為當(dāng)前類對(duì)象(Class類的實(shí)例)。每個(gè)類都有唯一的一個(gè)類對(duì)象。獲取類對(duì)象的方式:類名.class。
而對(duì)于互斥的場(chǎng)景,需要理解兩點(diǎn)說明:
1、靜態(tài)方法與非靜態(tài)方法同時(shí)聲明了synchronized,他們之間是非互斥關(guān)系的。原因在于,靜態(tài)方法鎖的是類對(duì)象而非靜態(tài)方法鎖的是當(dāng)前方法所屬對(duì)象。
2、當(dāng)Synchronized修飾的是兩段不同的代碼,但是鎖對(duì)象相同時(shí),兩個(gè)線程分別調(diào)用者兩段代碼時(shí)就是互斥的
所以你說的“一時(shí)刻只有一個(gè)線程能調(diào)用其中一個(gè)函數(shù)”(即互斥),判斷條件就是鎖對(duì)象是否相同,與方法類型無(wú)關(guān)。
回答6:對(duì)象方法的synchronized修飾,鎖為對(duì)象自身,也就是this;靜態(tài)方法的synchronized修飾,鎖為Class對(duì)象自身,也就是由類加載器創(chuàng)建的類對(duì)象;
