![]()
class Object{
element;
public synchronized void method(){}
}
【描述】線程1,對synchronized(element)訪問,線程2,對synchronized A()方法進行訪問。
【結論】獲取成員變量的鎖,與獲取對象的鎖,是獨立的。並不存在說,要獲取對象的鎖,就要求成員變量或神馬的都沒有鎖存在了。即,鎖成員變量與鎖整個對象是獨立的。
【描述】在前面描述的基礎上,如果method()方法內部,又需要對element()同步訪問。
【結論】那就得等了,等先前對element的鎖釋放。
![]()
class Object extends Thread{
public synchronized void fun(){}
public synchronized void run(){}
}
【描述】run()的時候,可以調用對象內synchronized B(),因為反正其已獲取到對象鎖。但如果另外一個線程,已獲取對象鎖,在訪問fun(),那么run()就必須得等了。
【結論】給run()前加synchronized需謹慎,可能造成的影響有:1. 如果run()一早獲取對象鎖,那么它跑起來,別人都別想訪問這里的同步方法了,例如fun();2. 如果run()一早沒有獲取對象鎖,那么它跑不起來,必須得等別人釋放了對象的鎖,如fun()執行結束,該線程才可以跑起來。
![]()
class Object{
public static synchronized void mm(){}
}
【描述】synchronized除了用於對象、成員變量,還可用於鎖“類”。
【備注】
1. 被synchronized聲明的方法被稱為同步方法,被其修飾的代碼塊稱為同步語句。無論是同步方法還是同步語句,只要聲明為同步了,在同一時刻,同一個對象的同步XX是不可以被同時訪問的,而不同對象之間的同步方法是互不干擾的。
2.
private byte[] lock= new byte[0];
Public void change() {
Synchronized(lock) {
}
}
自定義鎖注意事項:
a)必須是private,防止在類外部引用改變。
b)如果可能用到,重寫get方法,返回對象的clone,而不是本身。
3.
Class Foo {
public synchronizedstatic void methodAAA()// 同步的static 函數
{
//….
}
public void methodBBB() {
synchronized(Foo.class)// class literal(類名稱字面常量) 同一時刻,被修飾部分只有一個對象可以運行,因為它的聲明是針對類的。
} }
