Java的類鎖和物件鎖
阿新 • • 發佈:2019-02-07
類鎖和物件鎖不是同1個東西,一個是類的Class(對應的唯一的一個即這類的二進位制位元組碼)物件的鎖,1個是類的例項(!即new出的一個類的物件,一個類會有多個例項物件)的鎖。也就是說:1個執行緒訪問靜態synchronized的時候,允許另一個執行緒訪問物件的例項synchronized方法。反過來也是成立的,因為他們需要的鎖是不同的。
物件鎖:java的所有物件(即new出的一個類的物件,一個類會有多個例項物件)都含有1個互斥鎖,這個鎖由JVM自動獲取和釋放。執行緒進入synchronized方法的時候獲取該物件的鎖,當然如果已經有執行緒獲取了這個物件的鎖,那麼當前執行緒會等待;synchronized方法正常返回或者拋異常而終止,JVM會自動釋放物件鎖。這裡也體現了用synchronized來加鎖的1個好處,方法拋異常的時候,鎖仍然可以由JVM來自動釋放。
類鎖:物件鎖是用來控制例項方法之間的同步,類鎖是用來控制靜態方法(或靜態變數互斥體)之間的同步。其實類鎖只是一個概念上的東西,並不是真實存在的,它只是用來幫助我們理解鎖定例項方法和靜態方法的區別的。我們都知道,java類可能會有很多個物件,但是隻有1個Class物件,也就是說類的不同例項之間共享該類的Class物件。Class物件其實也僅僅是1個java物件,只不過有點特殊而已。由於每個java物件都有1個互斥鎖,而類的靜態方法是需要Class物件。所以所謂的類鎖,不過是Class物件的鎖而已。獲取類的Class物件有好幾種,最簡單的就是MyClass.class的方式。
/** * */ /** * 物件鎖和類鎖的使用 * <p>Title: MyTest</p> * <p>Description: </p> * <p>Company: </p> * @author 夏 傑 * @date 2015年12月17日 下午10:45:15 * @vesion 1.0 */ public class MyLock { /** * 物件鎖:形式1 * synchroined 修飾方法 直接方法名,對應的是當前類的new出來物件例項的例項碩 */ public synchronized void objLockMethod1() { System.out.println("in...objLockMethod1"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("out...objLockMethod1"); } /** * 物件鎖:形式2 * synchonced(this) 修飾程式碼塊 ,this代表的是當前類的例項物件鎖 */ public void objLockMethod2() { synchronized (this) { System.out.println("in...objLockMethod2"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("out...objLockMethod2"); } } /** * 類鎖:形式1 * static 類 用synchronized修飾 對應的是該類對應的Class類物件,只有唯一的一個 */ public static synchronized void classLock1() { System.out.println("classLock1------in"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("classLock1------out"); } /** * 類鎖:形式2 * synchronized (MyLock.class) * synchronized中的鎖使用 本類名.class 對應的是該類對應的Class類物件,只有唯一的一個 */ public static void classLock2() { synchronized (MyTest.class) { System.out.println("classLock2------in"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("classLock2------out"); } } }
物件鎖和類鎖的測試
/** * */ /** * <p>Title: Thread1</p> * <p>Description: </p> * <p>Company: </p> * @author 夏 傑 * @date 2015年12月17日 下午11:20:40 * @vesion 1.0 */ public class Thread1 implements Runnable{ MyLock myLock ; public Thread1(MyLock myLock) { this.myLock = myLock; } @Override public void run() { myLock.classLock1(); } }
/**
*
*/
/**
* <p>Title: Thread1</p>
* <p>Description: </p>
* <p>Company: </p>
* @author 夏 傑
* @date 2015年12月17日 下午11:20:40
* @vesion 1.0
*/
public class Thread2 implements Runnable{
MyLock myLock ;
public Thread2(MyLock myLock) {
this.myLock = myLock;
}
@Override
public void run() {
myLock.objLockMethod1();
}
}
/**
*
*/
/**
* <p>Title: ThreadMain</p>
* <p>Description: </p>
* <p>Company: </p>
* @author 夏 傑
* @date 2015年12月17日 下午11:27:05
* @vesion 1.0
*/
public class ThreadMain {
/**
* @param args
*/
public static void main(String[] args) {
MyLock myLock = new MyLock();
new Thread(new Thread1(myLock)).start();
new Thread(new Thread2(myLock)).start();
}
}
可以看出,類鎖和物件鎖不是同1個東西,一個是類的Class物件的鎖,1個是類的例項的鎖。也就是說:1個執行緒訪問靜態synchronized的時候,允許另一個執行緒訪問物件的例項synchronized方法。反過來也是成立的,因為他們需要的鎖是不同的。