首先來看一個問題
//有如下一個類A
class A {
public synchronized void a() {
}
public synchronized void b() {
}
}
//然后創(chuàng)建兩個對象
A a1 = new A();
A a2 = new A();
//然后在兩個線程中并發(fā)訪問如下代碼:
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
a1.a();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
a2.a();
}
});
//請問二者能否構成線程同步把夸?
//如果A的定義是下面這種呢宁舰?
class A {
public static synchronized void a() {
}
public static synchronized void b() {
}
}
首先公布結論吧:
第一個例子不能實現同步
第二個例子可以實現同步
Synchronized主修修飾對象為以下三種:
修飾普通方法 一個對象中的加鎖方法只允許一個線程訪問。但要注意這種情況下鎖的是訪問該方法的實例對象赏殃, 如果多個線程不同對象訪問該方法,則無法保證同步。
修飾靜態(tài)方法 由于靜態(tài)方法是類方法, 所以這種情況下鎖的是包含這個方法的類榴捡,也就是類對象;這樣如果多個線程不同對象訪問該靜態(tài)方法朱浴,也是可以保證同步的吊圾。
修飾代碼塊 其中普通代碼塊 如Synchronized(obj) 這里的obj 可以為類中的一個屬性达椰、也可以是當前的對象,它的同步效果和修飾普通方法一樣街夭;Synchronized方法 (obj.class)靜態(tài)代碼塊它的同步效果和修飾靜態(tài)方法類似砰碴。
Synchronized方法控制范圍較大, 它會同步對象中所有Synchronized方法的代碼板丽。
Synchronized代碼塊控制范圍較小呈枉, 它只會同步代碼塊中的代碼, 而位于代碼塊之外的代碼是可以被多個線程訪問的埃碱。
簡單來說 就是 Synchronized代碼塊更加靈活精確猖辫。