在Java中,鎖是實現多線程同步的重要機制之一。在鎖的實現中有一種叫做偏向鎖和輕量級鎖的鎖狀態。這兩種鎖狀態是Java語言中保證線程安全的關鍵,它們都是JDK 6之后的一個新特性。
什么是偏向鎖?
public class BiasedLockingTest { private static final int COUNT = 10000000; private static volatile String obj = new String("obj"); public static void main(String args[]) throws InterruptedException { synchronized (obj) { Thread.sleep(1000L); long beginTime = System.nanoTime(); for (int i = 0; i< COUNT; i++) { synchronized (obj) { i++; } } long endTime = System.nanoTime(); System.out.println("Time cost of biased locking : " + (endTime - beginTime) + " ns."); } } }
偏向鎖是一種針對單線程的鎖優化機制,它通過記錄線程ID來標記鎖對象,當線程再次請求鎖時,JVM會判斷線程ID是否與標記的線程ID一致,如果一致則無需進行互斥接管,從而消除了大量的互斥鎖的操作,提高了程序性能。
什么是輕量級鎖?
public class LightweightLockingTest { private static final int COUNT = 10000000; private static volatile Test test = null; private static void testWait(Test obj) { synchronized (obj) { try { obj.wait(0L); } catch (InterruptedException e) { } obj.value++; obj.notifyAll(); } } public static void main(String args[]) throws InterruptedException { long beginTime = System.nanoTime(); test = new Test(); test.start(); for (int i = 0; i< COUNT; i++) { testWait(test); } test.setStop(); long endTime = System.nanoTime(); System.out.println("Time cost of lightweight locking : " + (endTime - beginTime) + " ns."); } } class Test extends Thread { private boolean stop = false; public int value = 0; public void run() { while(!stop) { synchronized(this) { value++; this.notifyAll(); } } } public void setStop() { stop = true; } }
輕量級鎖是為了在鎖競爭較小的情況下,避免重量級鎖的性能損失而設計的。輕量級鎖的核心思想是獲取鎖時,不會直接進入同步代碼塊,而是在棧幀中開辟一塊用來存儲鎖對象的記錄,同時判斷該鎖對象是否被鎖定,如果未被鎖定則將鎖對象的對象頭指針指向鎖記錄,表示鎖定成功。如果鎖對象被鎖定了,則表示鎖競爭很激烈,JVM會直接升級為重量級鎖。