1. 程式人生 > >java中的類鎖與物件鎖

java中的類鎖與物件鎖

在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類鎖。