前言
廢話少說,主要是弄清楚概念上的東西,方便在寫程序中實際運用。
鎖的分類
對象鎖:synchronized修飾具體的類的實例對象,或者修飾類的一個方法
方法鎖:synchronized修飾類的一個方法
類鎖:synchronized修飾一個類的靜態方法,或者修飾諸如(Object.class)
具體的代碼
對象鎖
修飾具體的類的實例對象
public class Test {
public void method(){
synchronized(this){
System.out.println("我是對象鎖");
}
}
}
也可以這麼寫
public class Test{
private Test test=new Test();
public void method(){
synchronized(test){
System.out.println("我是對象鎖");
}
}
}
修飾類的一個方法時
public class Test{
public synchronized void method(){
System.out.println("我是對象鎖也是方法鎖");
}
}
方法鎖
上面已經提到了,如下
public class Test{
public synchronized void method(){
System.out.println("我是方法鎖也是對象鎖");
}
}
類鎖
public class Test{
public void method(){
synchronized(Test.class){
System.out.println("我是類鎖");
}
}
}
修飾類的靜態方法時
public class Test{
public synchronized static void method(){
System.out.println("我是類鎖");
}
}
至於爲什麼鎖靜態方法就是類鎖,稍作解釋:
因爲一個方法被定義爲靜態之後,那麼該方法就屬於這個類,而不是類的實例,在內存中也只有一份,我把這個僅有的一份鎖住了,其它要調用的只能去請求鎖,從而實現鎖類。
我之前的小疑問
關於鎖這裏,我之前一直有個疑問:爲什麼一般的操作都是鎖類,鎖實例對象,或者鎖方法,爲啥不鎖類的成員變量呢?
我現在的理解是:既然我鎖成員變量,肯定希望這個成員變量不被兩個線程同時更改造成不同步的問題,但是這個問題完全可以由鎖對象實例來解決,而且鎖對象實例範圍更加大一點,這個對象實例的所有成員變量的操作都是同步的,其實鎖類也可以,只不過鎖類只能鎖靜態成員變量。
關於這個小疑問,可能我的理解有失偏頗,還望不吝賜教!
後來補充:關於上面這個疑問,看到有的文章解釋的比較詳細,給出的理由是:實例變量和類變量本身就不持有鎖,所以無法對其進行加鎖。
然後關於這三種鎖的作用,方法鎖我=就不用贅述了,類鎖和對象鎖的作用:
對象鎖是用來控制實例方法之間的同步,類鎖是用來控制靜態方法(或靜態變量互斥體)之間的同步。
方法鎖(非靜態方法)其實也可以理解爲對象鎖,因爲要訪問synchronized
修飾的方法,要獲得對象鎖才行
一些易錯的地方
關於對象鎖這裏,如果是鎖的兩個不同的類對象實例,二者是不會同步的,因爲我們所說的對象鎖,只是針對同一個實例對象,如果是兩個不同的實例對象,不會具有競爭關係。說簡單點就是,多個對象會有多個鎖,互不干擾。
結語
暫時到這,實際使用如果有什麼問題,再拿來這裏結合分析。