今天看啥  ›  专栏  ›  兴趣使然的程序猿

3.8 ReentrantLock使用即解析

兴趣使然的程序猿  · CSDN  ·  · 2021-02-11 14:15

3.8 ReentrandLock

故名思意,ReentrandLock即可重入锁。可重入锁解决的是重入锁定的问题,重入锁定(Reentrance Lockout)指的是当一个线程执行逻辑时,需要两次获取锁,而该锁不可重入就会导致内部嵌套无法获取锁导致Reentrance Lockout发生。 Reentrance Lockout解决办法为一个线程两次获取锁的中间一定需要释放锁。


3.8.1 ReentrandLock继承关系

此处知道ReentrandLock是Lock接口的实现即可。
ReentrantLock继承关系


3.8.2 ReentradLock使用

声明锁即new创建锁。

static Lock lock = new ReentrantLock();
//修改时需要锁定的资源
static String text = "hello";
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

不加锁对text进行修改。

public static void modifyWithoutLock(){
    text += " "+Thread.currentThread().getName();
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
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());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

不加锁修改后text的长度为:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可知,对一个String变量多线程不加锁的情况下最后结果的长度很大概率是不一样的。



加锁对text进行修改。

public static void modify(){
	//使用lock方法枷锁
    lock.lock();
    try {
        text += " "+Thread.currentThread().getName();
    }catch (Exception e){
        e.printStackTrace();
    }
    finally {
    	//使用unlock方法解锁
        lock.unlock();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

加锁之后对多线程对text的修改最后的长度是一定的(这儿不能保证线程修改的顺序)。

3.8.2 ReentradLock方法介绍

ReentrandLock 作用
tryLock() 尝试获取锁
tryLock(long timeout, TimeUnit unit) 尝试获取锁,timeout是尝试获取锁的等待事件,超时不候,unit是等待时间的单位
unlock() 释放锁
getHoldCount() 当前线程持有该锁的次数
isHeldByCurrentThread() 当前线程是否持有该锁



3.8.3 ReentrandLock源码

构造方法

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

ReentrandLock默认是非公平锁, 也可以通过传入一个boolean fair的参数构造来声明该锁是公平锁还是非公平锁。


内部组成

在这里插入图片描述

private final Sync sync;
  • 1
  • 1

其内部由一个Sync sync属性组成,其是ReentradLock的内部类,Sync抽象内有NonfairSync和FairSync两种子类实现,分别表示非公平锁和公平锁。



加解锁方法

public void lock() {
    sync.lock();
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
public void unlock() {
    sync.release(1);
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

其具体实现其实是Sync的子类FairSync或者NonfairSync的方法,具体使用的哪个看构造的时候是公平锁还是非公平锁,对于Sync的解析放在后边再说。




原文地址:访问原文地址
快照地址: 访问文章快照