公众号merlinsea
- 可重入锁的定义:
- 程调用方法A中获取了锁lock,如果方法A中还调用了方法B,并且方法B还可以获取方法A已经获取的锁,且不会发生死锁,那么lock就是可重入锁。可重入锁针对的是同一个线程里调用不同的方法可重入,并且这个线程执行notify()方法的条件在于该线程内的所有方法都释放了这把锁。
- 可重入锁的核心实现:
- 需要记录谁持有了这把锁
- 需要记录这把锁被同一个线程重入了多少次
- 代码实现
public class ReentrantLock { private boolean isLock = false; //锁的状态 private Thread lockOwner = null; //持有锁的线程 private int lockedCount = 0; // 重入的次数 public synchronized void lock() throws InterruptedException{ System.out.println("进入lock()的线程 = " + Thread.currentThread().getName()); Thread thread = Thread.currentThread(); while(isLock && thread != lockOwner){ // 锁已经被持有了并且当前希望进入的线程不等于持有锁的线程 // 注意我们进行判断锁是否可以进入的时候需要用while循环而不是if System.out.println("进入wait状态的线程 = " + thread.getName()); System.out.println("当前持有锁的线程 = " + lockOwner.getName()); System.out.println("锁被冲入的次数 = " + lockedCount); wait(); // 阻塞于this锁 } isLock = true; lockOwner = thread; lockedCount++; // 代表重入次数 } public synchronized void unlock(){ System.out.println("进入unlock()的线程 = " + Thread.currentThread().getName()); Thread thread = Thread.currentThread(); if(thread == lockOwner){ // 谁加锁 谁解锁 lockedCount--; if(lockedCount==0){ // 必须是当前线程已经没有方法持有这个锁了才进行是否 lockOwner = null; isLock = false; notify(); // 唤醒阻塞在this锁上的一个线程 } } } }