java中的類鎖與物件鎖
阿新 • • 發佈:2018-12-11
在java中使用synchronized進行同步,鎖的型別有類鎖與物件鎖之分。
一、物件鎖
當多個執行緒操作同一個例項的時候才產生作用。
1、修飾程式碼塊
使用this:屬於物件鎖
public void do() {
synchronized (this) { // this:屬於物件鎖 與public synchronized void doVoid() { } 同步
System.out.println("is base");
}
2、修飾方法
這種直接修飾在方法是咱個情況?其實和修飾程式碼塊類似,只不過此時預設使用的是this,也就是當前物件的鎖。這樣寫起程式碼來倒也比較簡單明確。與第一點修飾程式碼塊的區別主要還是控制粒度的區別。
public synchronized void doVoid() { } //物件鎖 與synchronized (this){} 同步
多執行緒同時執行上述兩種方法是需要同步的,獲取物件鎖才能執行。
二、類鎖
當多個執行緒操作不同的例項,但是這些例項同屬於一個類時候產生作用。
1、修飾靜態方法
private static synchronized void method1(){ //類鎖
//與synchronized (BaseClass.class){} 同步
}
靜態方法難道有啥不一樣嗎?確實是不一樣的,此時獲取的鎖已經不是this了,而this物件指向的class,也就是類鎖。因為Java中的類資訊會載入到方法常量區,全域性是唯一的。這其實就提供了一種全域性的鎖。
2、使用xxx.class
public static void doStaticVoid() {
synchronized (BaseClass.class) { //類鎖,此方法執行,則與private static synchronized void method1()方法同步
//這種情況其實和修改靜態方法時比較類似,只不過還是一個道理這種方式可以提供更靈活的控制粒度。
}
}
}
多執行緒同時執行上述兩種方法是需要同步的,獲取類鎖才能執行。
三、總結
何時產生同步?
假如我們有兩個 Student類的例項stu1、stu2。
Student類中的方法如下:
class Student{
//物件鎖
public void fun1() {
synchronized (this) {
.....
}
//物件鎖
public synchronized void fun2() {
.....
}
//類鎖
public void fun3() {
synchronized (Student.class) {
.....
}
//類鎖
public synchronized void fun4() {
.....
}
}
1、 執行緒A操作stu1中的物件鎖方法即fun1或者fun2,執行緒B操作stu2中的物件鎖方法即fun1或者fun2,則A、B執行緒不會產生同步,一個獲取stu1的物件鎖,一個獲取stu2的物件鎖,何來同步呢?
若A、B兩執行緒同時操作stu1中的物件鎖方法即fun1或者fun2,則會產生同步。
2、 執行緒A操作stu1中的類鎖方法即fun3或者fun4,執行緒B操作stu2中的類鎖方法即fun3或者fun4,則A、B執行緒產生同步,兩執行緒獲取的是一個鎖,即 Student類鎖。