因此,ReentrandLock可以重新入锁。重入锁可以解决重入锁的问题。重入锁(Reentrance Lockout)这意味着当一个线程执行逻辑时,需要两次获得锁,锁不能重新进入,导致内部嵌套无法获得锁,导致Reentrancee Lockout发生了。Reentrance Lockout解决方案是在一个线程两次获取锁的中间释放锁。
3.8.1 Rentrandlock继承关系这里知道ReentrandLock是Lock接口的实现。
3.8.2 Reentradlock使用声明锁是new创建的锁。
static Lock lock = new ReentrantLock();////修改时需要锁定的资源staticc String text = "hello";
不加锁修改text。
public static void modifyWithoutLock(){ text += " "+Thread.currentThread().getName();}
public static void main(String[] args) throws InterruptedException { modifyWithoutLock(); for (int i=0;i<100;i++) { new Thread(() -> { modifyWithoutLock(); }).start(); } Thread.sleep(50); System.err.println(text.length());}
修改后text的长度为:
可以看出,在String变量多线程不锁定的情况下,最终结果的长度很有可能会有所不同。
加锁修改text。
public static void modify(){///使用lock方法束链 lock.lock(); try { text += " "+Thread.currentThread().getName(); }catch (Exception e){ e.printStackTrace(); } finally { ///使用unlock解锁 lock.unlock(); }}
对text进行多线程修改后的最终长度是一定的(这里不能保证线程修改的顺序)。
3.8.2 介绍Reentradlock方法ReentrandLock
作用
tryLock()
尝试获取锁
tryLock(long timeout, TimeUnit unit)
试着获得锁,timeout是试着获得锁的等待事件,超时,unit是等待时间的单位
unlock()
释放锁
getHoldCount()
当前线程持有锁的次数
isHeldByCurrentThread()
当前线程是否持有锁
…
…
3.8.3 Rentrandlock源码构造方法public ReentrantLock() { sync = new NonfairSync();}/** * Creates an instance of {@code ReentrantLock} with the * given fairness policy. * 如果fair是true,结构是公平的锁 * @param fair {@code true} if this lock should use a fair ordering policy */public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync();}
默认情况下,Reentrandlock是一个不公平的锁,也可以通过输入booleann fair的参数结构来声明锁是公平锁还是非公平锁。
内部组成private final Sync sync;
内部由一个Sync内部组成 Sync属性由Reentradlock组成,Sync抽象中有两种子类:NonfairSync和FairSync,分别表示非公平锁和公平锁。
加解锁方法public void lock() { sync.lock();}
public void unlock() { sync.release(1);}
它的具体实现实际上是Sync子类FairSync或NonfairSync的方法,具体使用取决于结构是公平锁还是非公平锁,Sync的分析放在后面。