Java裏面遞歸鎖又叫可重入鎖
-
定義
同一個線程在內層方法獲取到鎖之後,在進入內層方法會自動獲取鎖
也就是說
線程可以進入任何一個他已經擁有的鎖所同步着的代碼塊
-
代碼驗證
lock 和 synchronized 都是遞歸鎖
2.1 synchronized 代碼驗證
/** * @Author: xiaoshijiu * @Date: 2019/11/25 * @Description: synchronized遞歸鎖代碼驗證 */ public class SynchTest { public synchronized void test() { System.out.println(Thread.currentThread().getName()); // 調用test2方法,test2方法也是經過synchronized加鎖的方法 test2(); } public synchronized void test2() { System.out.println(Thread.currentThread().getName()); } public static void main(String[] args) { SynchTest synchTest = new SynchTest(); for (int i = 0; i < 5; i++) { new Thread(() -> { synchTest.test(); }, "T" + i).start(); } } /** * 運行結果表明:同一個線程獲取到外層方法的鎖後,會自動獲取到內層方法的鎖 * 即遞歸鎖 */ }
運行結果
運行結果表明:內層方法雖然加鎖了,但是並不需要再競爭鎖資源,即
同一個線程獲取到外層方法的鎖後,會自動獲取到內層方法的鎖,即遞歸鎖2.2 lock 代碼驗證
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Author: xiaoshijiu * @Date: 2019/11/25 * @Description: Lock是遞歸鎖代碼驗證 */ public class LockTest { Lock lock = new ReentrantLock(); public void test() { lock.lock(); try { System.out.println(Thread.currentThread().getName()); test2(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void test2() { lock.lock(); try { System.out.println(Thread.currentThread().getName()); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public static void main(String[] args) { LockTest lockTest = new LockTest(); for (int i = 0; i < 5; i++) { new Thread(() -> { lockTest.test(); }, "T" + i).start(); } } /** * 運行結果表明:同一個線程獲取到外層方法的鎖後,會自動獲取到內層方法的鎖 * 即遞歸鎖 */ }
運行結果:
運行結果表明:內層方法雖然加鎖了,但是並不需要再競爭鎖資源,即
同一個線程獲取到外層方法的鎖後,會自動獲取到內層方法的鎖,即遞歸鎖