首页 > 其他分享 >JUC 常用类 ReentrantLock

JUC 常用类 ReentrantLock

时间:2023-07-12 10:12:50浏览次数:31  
标签:JUC 常用 return Thread int ReentrantLock Sync 线程 final

  • ReentrantLock 类内部总共存在 Sync、NonfairSync、FairSync 三个类

  • NonfairSync与FairSync类继承自 Sync 类

  • Sync类继承自 AbstractQueuedSynchronizer 抽象类

内部类

Sync

abstract static class Sync extends AbstractQueuedSynchronizer {
    // 序列号
    private static final long serialVersionUID = -5179523762034025860L;
    
    // 获取锁
    abstract void lock();
    
    // 非公平方式获取
    final boolean nonfairTryAcquire(int acquires) {
        // 当前线程
        final Thread current = Thread.currentThread();
        // 获取状态
        int c = getState();
        if (c == 0) { // 表示没有线程正在竞争该锁
            if (compareAndSetState(0, acquires)) { // 比较并设置状态成功,状态0表示锁没有被占用
                // 设置当前线程独占
                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;
    }
    
    // 试图在共享模式下获取对象状态,此方法应该查询是否允许它在共享模式下获取对象状态,如果允许,则获取它
    protected final boolean tryRelease(int releases) {
        int c = getState() - releases;
        if (Thread.currentThread() != getExclusiveOwnerThread()) // 当前线程不为独占线程
            throw new IllegalMonitorStateException(); // 抛出异常
        // 释放标识
        boolean free = false; 
        if (c == 0) {
            free = true;
            // 已经释放,清空独占
            setExclusiveOwnerThread(null); 
        }
        // 设置标识
        setState(c); 
        return free; 
    }
    
    // 判断资源是否被当前线程占有
    protected final boolean isHeldExclusively() {
        // While we must in general read state before owner,
        // we don't need to do so to check if current thread is owner
        return getExclusiveOwnerThread() == Thread.currentThread();
    }

    // 新生一个条件
    final ConditionObject newCondition() {
        return new ConditionObject();
    }

    // Methods relayed from outer class
    // 返回资源的占用线程
    final Thread getOwner() {        
        return getState() == 0 ? null : getExclusiveOwnerThread();
    }
    // 返回状态
    final int getHoldCount() {            
        return isHeldExclusively() ? getState() : 0;
    }

    // 资源是否被占用
    final boolean isLocked() {        
        return getState() != 0;
    }

    /**
    * Reconstitutes the instance from a stream (that is, deserializes it).
    */
    // 自定义反序列化逻辑
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        setState(0); // reset to unlocked state
    }
}

NonfairSync

NonfairSync类继承了Sync类,表示采用非公平策略获取锁,其实现了Sync类中抽象的lock方法,源码如下:

// 非公平锁
static final class NonfairSync extends Sync {
    // 版本号
    private static final long serialVersionUID = 7316153563782823691L;

    // 获得锁
    final void lock() {
        if (compareAndSetState(0, 1)) // 比较并设置状态成功,状态0表示锁没有被占用(插队)
            // 把当前线程设置独占了锁
            setExclusiveOwnerThread(Thread.currentThread());
        else // 锁已经被占用,或者set失败
            // 以独占模式获取对象,忽略中断
            acquire(1); 
    }

    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

从 lock 方法的源码可知,每一次都尝试插队

FairSync

FairSync类也继承了Sync类,表示采用公平策略获取锁,其实现了Sync类中的抽象lock方法,源码如下:

// 公平锁
static final class FairSync extends Sync {
    // 版本序列化
    private static final long serialVersionUID = -3000897897090466540L;

    final void lock() {
        // 以独占模式获取对象,忽略中断
        acquire(1);
    }

    /**
    * Fair version of tryAcquire.  Don't grant access unless
    * recursive call or no waiters or is first.
    */
    // 尝试公平获取锁
    protected final boolean tryAcquire(int acquires) {
        // 获取当前线程
        final Thread current = Thread.currentThread();
        // 获取状态
        int c = getState();
        if (c == 0) { // 状态为0
            if (!hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) { // 不存在已经等待更久的线程并且比较并且设置状态成功
                // 设置当前线程独占
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        else if (current == getExclusiveOwnerThread()) { // 状态不为0,即资源已经被线程占据
            // 下一个状态
            int nextc = c + acquires;
            if (nextc < 0) // 超过了int的表示范围
                throw new Error("Maximum lock count exceeded");
            // 设置状态
            setState(nextc);
            return true;
        }
        return false;
    }
}

标签:JUC,常用,return,Thread,int,ReentrantLock,Sync,线程,final
From: https://www.cnblogs.com/hangychn/p/17546784.html

相关文章

  • 常用性能监测工具介绍
    1常用工具介绍系统监控是一种向用户提供有关系统实际计时行为的数据的有用方法。用户可以使用这些监视器提供的数据执行进一步的分析。系统监控的目标之一是确定当前执行是否满足指定的技术要求。这些监视工具检索通常查看的信息,可以通过命令行或图形用户界面(由系统管理员确定)......
  • Docker CLI docker logs 常用命令
    Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。Docker是内核虚拟化,不使用Hypervisor是不完全虚拟化,依赖内核的特性实现资源隔离。本文主要介绍DockerCLI中d......
  • linux基础命令及常用命令总结
    1.ls命令ls命令是最基础的命令之一,作用是列出当前目录下所有的文件和目录。ls命令有很多选项可以使用,比较常用的是-l选项,可以以详细信息的形式列出所有文件和目录的信息。示例:列出当前目录下的所有文件和目录,使用-l选项#ls-i2.cd命令cd命令可以进入指定的目录。在Linux......
  • JUC包常用类原理
    概要放眼望去,java.util.concurrent包下类大致包括:atomic原子类、锁、并发集合、线程池、工具类。我们挑重要的了解一下。Atomic原子类Java针对并发编程已经有了各种锁,为什么还需要原子类?原子类一定有些特别的应用场景?在很多时候,我们需要的仅仅是一个简单的、高效的、线程安......
  • Spring中最常用的11个扩展点
    1.自定义拦截器springmvc拦截器根spring拦截器相比,它里面能够获取HttpServletRequest和HttpServletResponse等web对象实例。springmvc拦截器的顶层接口是:HandlerInterceptor,包含三个方法:1.2)preHandle目标方法执行前执行1.2)postHandle目标方法执行后执行1.3)afterCompletio......
  • 常用Dos命令
    常用Dos命令打开方式windows键+R(打开cmd的推荐方式)盘符切换C:D:查看当前目录下的所有文件dir切换目录cd同级目录进入下一级目录cd..返回上一级目录通过“cd/d地址”可以访问任意地址清理屏幕cls退出终端exit查看电脑ipipconfig打开应用略ping命令ping+......
  • git 常用命令
    克隆远程库gitclonexxx.git查看本地分支gitbranch 拽取远程分支更新git fetch origin查看远程分支gitbranch-r 切换分支gitcheckout[branch]从当前分支创建新分支,并切换到新分支gitcheckout-bdevelop从远程分支创建新分支,并切换到新分支gitcheckout-......
  • ansible常用模块
    ansible核心内容(模块学习)ansible执行命令结果(状态颜色)绿色:命令以用户期望的执行了,但是状态没有发生改变;黄色:命令以用户期望的执行了,并且状态发生了改变;紫色:警告信息,说明ansible提示你有更合适的用法;红色:命令错误,执行失败;蓝色:详细的执行过程;官网文档如果说学ansible......
  • Linux 发布常用命令
    移动mv原文件路径目标路径复制(所有文件含子目录)cp-r源文件路径目标路径查看进程ps-ef|grep要查看的进程名杀进程kill-9端口号查看历史命令history文件上传rz打包解压.tar格式解包:tarxvfFileName.tar打包:tarcvfFileName.tarDirName(注:tar是打包,不......
  • JVM常用工具分析
    JVM基础分析、故障解决工具常用jdk工具jps:JvmProcessStatusTool显示系统内全部的虚拟机进程;jstat:JvmStatisticsMonitoringTool动态收集指定进程运行时数据;jinfo:ConfigurationInfoForJava实时显示或调整虚拟机的配置信息;jmap:MemoryMapForJava生......