当前位置: 首页 > 图灵资讯 > 技术篇> 3.8 ReentrantLock使用即解析

3.8 ReentrantLock使用即解析

来源:图灵教育
时间:2023-06-06 09:31:38

3.8 ReentrandLock

因此,ReentrandLock可以重新入锁。重入锁可以解决重入锁的问题。重入锁(Reentrance Lockout)这意味着当一个线程执行逻辑时,需要两次获得锁,锁不能重新进入,导致内部嵌套无法获得锁,导致Reentrancee Lockout发生了。Reentrance Lockout解决方案是在一个线程两次获取锁的中间释放锁。

3.8.1 Rentrandlock继承关系

这里知道ReentrandLock是Lock接口的实现。

3.8 ReentrantLock使用即解析_ReentrantLock使用

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的长度为:

3.8 ReentrantLock使用即解析_ReentrantLock使用_02

3.8 ReentrantLock使用即解析_并发编程_03

3.8 ReentrantLock使用即解析_ReentrantLock解析_04

可以看出,在String变量多线程不锁定的情况下,最终结果的长度很有可能会有所不同。

加锁修改text。

public static void modify(){///使用lock方法束链    lock.lock();    try {        text += " "+Thread.currentThread().getName();    }catch (Exception e){        e.printStackTrace();    }    finally {    ///使用unlock解锁        lock.unlock();    }}

3.8 ReentrantLock使用即解析_并发编程_05

对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的参数结构来声明锁是公平锁还是非公平锁。

内部组成

3.8 ReentrantLock使用即解析_ReentrantLock解析_06

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的分析放在后面。