可重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。在释放的时候,也需要相应的释放n次
synchronized 和 ReentrantLock 都是可重入锁。
可重入锁的意义之一在于防止死锁。
构造方法如图所示:默认实现的是非公平锁
基本使用
new Thread(){ @Override public void run() { super.run(); //state 由0->1 至此同一线程的锁变成无锁状态 reentrantLock.lock(); System.out.println(Thread.currentThread().getId()); set(); //state 由1->0 至此同一线程的锁变成无锁状态 reentrantLock.unlock(); } }.start(); public static void set() { //第二个断点打在这 state 1->2 reentrantLock.lock(); System.out.println(Thread.currentThread().getId()); //2->1 reentrantLock.unlock(); }
第一次 state=0 if成立
setExclusiveOwnerThread将当前线程和这把锁进行绑定,防止其他线程占有
进入set方法 也就是第二个lock,很显然这里就不是0了 所以走else
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } //这里为啥进入了非公平锁的获取是因为在构造ReentranLock时如果是空构造函数, //就是非公平锁 后面会将公平锁和非公平锁的底层原理 protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } ///来到了ReentrantLock的nonfairTryAcquire具体实现方法 先获取state 还是先比较state是不是0 如果不是 就比较当前线程是不是绑定的线程 //是的话state+1 final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }