欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

JAVA REENTRANTLOCK、S 劳务派遣信息管理系统 EMAPHORE 的实现与 AQS 框架

点击: 次  来源:宝鼎软件 时间:2017-08-18

原文出处: forever

引言

ReentrantLock是JDK提供的一个可重入互斥锁,所谓可重入就是同一个锁答允被已经得到该锁的线程从头得到。可重入锁的长处可以在递归算法中利用锁,不行重入锁则导致无法在递归算法中利用锁。因为第二次递归时由于第一次递归已经占有锁,而导致死锁。本文我们将探讨JDK中ReentrantLock的实现。

Semaphore是JDK提供的一个可共享的同步组建,有n个许可,多个线程可以配合去得到许可,当线程申请的许可小于n时即可乐成申请,不然申请失败。

AQS(AbstractQueuedSynchronizer)是Java实现同步组建的基本框架,一般以静态内部类的形式实此刻某个同步组件类中,通过署理的方法向外提供同步处事,ReentrantLock和Semaphore都是基于AQS实现的同步组件,前者是独有式同步组建,即一个线程得到后,其他线程无法得到。后者是共享式同步组件,一个线程得到后,在满意的条件下,其他线程也可以得到。

AQS事情道理

AQS是Java实现同步组建的基本框架,其根基思想是用一个volatile int state变量来暗示当前同步组件的状态,用getState()获取同步组件的状态,用compareAndSet(int expect, int update)来对state状态举办操纵,compareAndSet可以担保对state变量更新值的原子性。AQS中许多要领是final的,即不答允用户包围,软件开发,用户自界说的要领一般有:

  • tryAcquire: 独有式获取同步状态,该函数一般首先查询state的值,假如state不答允继承被获取,直接返回false。假如state答允继承被获取,CAS实验更新state的值,乐成返回true,失败返回false
  • tryAcquireShared:共享式的获取同步状态,该一般是在CAS死轮回获取state的值,计较state被获取后的值,假如该值为负数,直接返回负数暗示失败,假如该值为正值,则用CAS更新该值,当CAS更新失败时,反复上述步调,直至返回负数或CAS更新乐成返回正值。
  • tryRelease:独有式的释放同步状态
  • tryReleaseShared:共享式的释放同步状态,一般在CAS死轮回中重复实验,直至释放乐成
  • isHeldExclusively:判定当前同步器是否被当前线程占有
  • AQS提供的模板要领有:

  • acquire:独有式的获取同步状态,获取乐成则返回,获取失败则会进入期待行列,该要了解挪用用户自界说的tryAcquire函数
  • acquireInterruptibly:与acquire雷同,差异在于当进入期待行列时,碰着间断会抛出InterruptedException异常,用户可以处理惩罚该间断异常
  • tryAcquireNanos:在acquireInterruptibly的基本上增加了时间限制,一按时间内没有乐成获取则返回false
  • acquireShared:共享式的获取同步状态,乐成则返回,失败则进入期待行列,该要了解挪用用户自界说的tryAcquired函数
  • acquireSharedInterruptibly:在期待行列可以相应间断,与上雷同
  • tryAcquireShared:在acquireSharedInterruptibly增加了超时限制
  • release:独有式的释放同步状态,会挪用用户自界说tryRelease函数
  • releaseShared:共享式的释放同步状态,会挪用用户自界说tryReleaseShared函数
  • getQueuedThreads:获取期待行列线程荟萃
  • ReentrantLock源码阐明

    ReentrantLock的默认结构函数是

    public ReentrantLock() {
            sync = new NonfairSync();
    }

    NonfairSync担任了Sync,Sync是一个抽象类,并担任了抽象类AbstractQueuedSynchronizer。
    ReentrantLock是一个独有式的锁,所以它需要实现tryAcquire函数和tryRelease函数

    tryAcquire函数源码如下

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

    nonfairTryAcquire(acquires)源码如下

    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;
    }
  • 先获得当前线程
  • 查询当前state值,假如为0则说明当前锁还未被其他线程获取,则实验CAS得到锁,乐成则把占有锁的线程配置为当前线程,返回true。失败返回false。
  • 假如state不为0则说明该锁已经被其他线程获取,则查抄得到锁的线程是否是当前线程以实现可重入特性,假如是,软件开发,则更新state的值,并返回true。此处更新不需要CAS,因为只有当前线程可以操纵state。
  • 其他环境返回false