首页 > 编程知识 正文

c++ 多线程,reentrantlock

时间:2023-05-04 22:20:38 阅读:31432 作者:3439

目录可重读锁有两种实现方法。 1、AbstractQueuedSynchronizer源代码分析1、继承关系2、构造函数3、属性2、ReentrantLock源代码分析1、继承关系2、构造函数3、属性和内部类同步

重新锁定有两种实现方法。

1、公平锁:先来后到,先抢锁线程先执行;

2、公平锁:你先来再来,谁抢谁先执行;

这两个锁的实现都用于一个名为AbstractQueuedSynchronizer的类(简称AQS,实现锁的重要类),该类基于FIFO队列,在锁和其他相关同步设备的基础框架中由于该同步器(以下简称同步器)使用int来表示状态,因此要了解ReentrantLock (可重新锁定的实现原理),必须先了解AQS,所以先看看AQS的实现:

一、AbstractQueuedSynchronizer源代码解析1、继承关系

2、构造函数

3、属性顺便还分析了属性相关的内部类:

AQS状态:

state=0表示锁定处于空闲状态

state0表示锁定已被占用

状态0表示溢出

那么,要知道这些基本属性和方法就好了。 解析ReentrantLock源代码时将调用其他AQS方法。

让我们看看ReentrantLock的源代码。

二、ReentrantLock源代码解析1、继承关系

2、构造函数

3、属性和内部类Sync类源代码(公平锁和非公平锁的父类) :

从NonfairSync (非公平性锁定源代码: lock ) )方法看:

NonFairSync获取锁定的过程总结如下:

1、第一次通过CAS强制抢锁,想抢锁失败就再次抢锁;

2、第二次尝试抢锁,首先判断锁是否被占用,如果state=0,直接通过CAS获取锁,

如果获取成功,请更正state,将当前线程计数为AQS,然后返回正常; 如果确定锁已被占用,如果占用锁的线程是当前线程,则直接修改state并返回正常;

以上都不满意:

将当前线程添加到存储线程的双向链表中(如果当前双向链表为空,则初始化头部节点。 头部节点是空节点,没有任何内容。 然后,将存储当前线程的节点添加到链表之后,并更新链表的末尾指针。) ),

尝试获取锁定(对新添加的节点进行排队后,该节点有两种状态:获取锁定或挂起锁定,如果该节点不是头节点的下一个节点,则检查该节点是否应该挂起) 如果当前节点的前驱节点不是头节点,则前驱节点会通知您,并且他可以放心地锁定。 如果当前节点的前体节点是头部节点,则尝试在tryAcquire中获取锁定直到成功;如果成功获取锁定,则使当前节点成为头部节点。)。

从lock )方法查看FairSync (公平性锁定)源代码。

总结FairSync获取锁定的过程。

1、尝试获取锁定

如果锁定未被占用,则确定当前线程是否满足条件(AQS队列为空或当前线程位于AQS队列的开头),修改state以将当前线程记录在锁定中,然后返回正常

如果锁定已被占用,且当前线程占用了锁定,请更正state并返回正常

如果以上得不到满足,就会失败并返回;

2、未能锁定时,将线程添加到AQS队列中;

可重新调整的锁包括ConditionObject。 这是Condition接口的唯一实现类,Condition提供了比wait、notify和notifyAll更灵活的线程间通信机制,并分析源代码。

最后是unlock (谈谈方法:

4、方法其他方法比较简单,以下介绍ReentrantLock类的其他方法。

方法查询int getHoldCount )、当前线程保持此锁定的次数(即lock )以及调用方法的次数。 int getQueueLength ) )返回等待获取此锁定的估计线程数。 集成队列长度(condition condition )返回与此锁定相关的条款和条件的线程估计数。 booleanhasqueuedthread (thread thread )、boolean hasQueuedThreads )查询显示: 指定当前线程是否正在等待获取此锁定布尔条件约束(boolean isFair )查询;如果是公平锁定,则为true(reentrantlock为默认锁定) isLocked ) )确定查询中是否有线程保留此锁定。 lockInterruptbly ()在当前线程未中断时获取锁定; 如果被中断,则抛出(“异常”(InterruptedException ) tryLock ) )并尝试获取锁定。 如果锁定不在另一个线程中,则获取该锁定。 也就是说,成功获取并返回true。 否则,获取false (锁已获取到另一个线程) trylock (trylock ) longtimeout,如果timm锁不在另一个线程中,则获取该锁,即获取成功并返回true,并且未获取该锁区别:

非公平锁获得两次锁;

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。