对jdk并发包理解(二)

concurrent 包下locks(锁相关)包

首先看下最常见的Lock接口(如无法找到该类在jdk中的位置请查看对jdk并发包理解(一))

在这里插入图片描述
个人理解的大概的意思是:锁获取的三种形式(可中断、不可中断和定时),Lock不支持锁获取过程中进行中断,如果中断锁必须遵守此接口中定义的中断语义,要么完全中断,要么仅在方法项上中断(中断通常意味着取消,中断不会检查,实现可能会倾向于响应中断而不是正常的方法返回。)
Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,Lock中定义了以下方法获取Condition:
Condition newCondition();
示例:

lock.lock();//加锁
try {
      Thread.sleep(5000);
      condition.signal();//唤醒需要该锁的其他线程
}catch (Exception e){
 
}finally {
      lock.unlock();//释放锁
}

ReentrantReadWriteLock实现了ReadWriteLock(读写锁)

读写锁不支持升级,但是可以降级,什么意思?(如下)

ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();  
 rwLock.writeLock().lock();           
 rwLock.readLock().lock(); //获取了写锁后获取读锁是可以的,反之则获取不到,进入死锁

实例化代码:

public ReentrantReadWriteLock(boolean fair) {
		//如果当前线程不是锁的占有者,则NonfairSync并不判断是否有等待队列,直接使用compareAndSwap去进行锁的占用;
        //如果当前线程不是锁的占有者,则FairSync则会判断当前是否有等待队列,如果有则将自己加到等待队列尾;
        //FairSync和NonfairSync
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }

最终都继承AbstractOwnableSynchronizer
在这里插入图片描述

LockSupport(应该可以理解为“线程阻塞器”)

首先开发者在注释中保留了这样一段代码
在这里插入图片描述
先去查看一下这个park()方法
在这里插入图片描述
在这里插入图片描述

如果许可证可用直接返回,如果许可证不可用,调用这个方法应该相当于阻塞这个线程,放开该线程的方法是调用unpark()方法,或者其他线程中断该线程,或该线程本身报错,parkNanos比park多一个设置时间

ReentrantLock(可重入互斥锁)

其基本行为和语义与使用同步方法和语句访问的隐式监视锁相同,但具有扩展功能。 可重入锁属于上次成功锁定但尚未解锁它的线程。当锁不属于另一个线程时,调用锁的线程将返回,并成功获取锁。如果当前线程已经拥有锁,则该方法将立即返回。这可以使用isHeldByCurrentThread和getHoldCount方法进行检查。 此类的构造函数接受可选的公平性参数。当设置为true时,在争用下,锁有利于向等待时间最长的线程授予访问权限。否则,此锁不保证任何特定的访问顺序。与使用默认设置的程序相比,使用由许多线程访问的公平锁的程序可能显示出较低的总体吞吐量(即,较慢;通常要慢得多),但是在获得锁和保证没有饥饿的时间上差异较小。但是请注意,锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的多个线程中的一个线程可以连续多次获得公平锁,而其他活动线程则没有进行并且当前没有持有该锁。还要注意,untimed tryLock()方法不支持公平性设置。如果锁可用,即使其他线程正在等待,它也会成功。 建议的做法是总是在调用之后立即使用try块锁定,最典型的是在构建之前/之后。

除了实现锁接口之外,这个类还定义了许多公共和受保护的方法来检查锁的状态。其中一些方法只对仪器和监测有用。 此类的序列化与内置锁的行为相同:反序列化的锁处于未锁定状态,而与序列化时的状态无关。 此锁最多支持同一线程的2147483647个递归锁。尝试超过此限制会导致锁定方法抛出错误。

isLocked方法

判断该线程是否有锁,返回boolean

isFair方法

获取锁的公平性,返回boolean

isHeldByCurrentThread方法

判断当前线程是否持有锁,类似于自旋锁,返回boolean

getOwner方法

返回当前拥有此锁的线程,如果不拥有则返回null。当不是所有者的线程调用此方法时,返回值反映当前锁状态的最佳近似值。例如,所有者可能暂时为空,即使有线程试图获取锁,但还没有这样做。此方法旨在促进提供更广泛的锁监控设施的子类的构造。

hasQueuedThreads方法

查询是否有线程正在等待获取此锁。请注意,由于取消操作可能随时发生,因此真正的返回并不保证任何其他线程都会获得该锁。此方法主要用于监视系统状态

hasQueuedThread方法

查询给定线程是否正在等待获取此锁。请注意,由于取消操作可能随时发生,因此真正的返回并不保证此线程将获得此锁。此方法主要用于监视系统状态。

其他方法不在此处具体介绍了。。。

StampedLock(1.8之后引入,读写锁的升级)

一种基于功能的锁,具有三种控制读写访问的模式。冲压锁的状态由版本和模式组成。锁获取方法返回一个表示并控制对锁状态的访问的戳;这些方法的“try”版本可能会返回特殊值0,以表示获取访问失败。锁释放和转换方法需要stamp作为参数,如果它们与锁的状态不匹配,则会失败。三种锁分别是:读锁,写锁,乐观读锁。
StampedLock的调度策略并不总是倾向于读写器,反之亦然。所有的“尝试”方法都是尽力而为的,不一定符合任何调度或公平策略。任何用于获取或转换锁的“try”方法的零返回都不会携带有关锁状态的任何信息;后续调用可能会成功。
StampedLock基于CLH锁减少内存争夺。

concurrent本类的包将会在下一篇整理。锁这部分就整理到这里,欢迎留言!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值