ReentrantLock可重入锁又是怎么回事?

2024-08-28 14:36

本文主要是介绍ReentrantLock可重入锁又是怎么回事?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:有关Synchronized锁的知识可以参考我上篇写的内容synchronized必知必会的知识点


一:ReentrantLock的实现原理

锁的实现原理基本是为了达到一个目的:让所有的线程都能看到某种标记。Synchronized通过在对象头中设置标记实现了这一目的,是一种/原生的锁实现方式,而ReentrantLock以及所有的基于LocK接口的实现类,都是通过用一个volitle修饰的int型变量,并保证每个线程都能拥有对该int的可见性和原子修改,其本质是基于所谓的AQS框架。

二:AQS框架又是怎么回事 

AQS (AbstractQueuedsynchronizer类)是一个用来构建铁和同步器的框架,各种LocK包中的锁(常用的有ReentrantLock、ReadWriteLock),以及其他如Semaphore,CountDownLatch,甚至是早期的FutureTask等,都是基于AQS来构建

1.AQS在内部定义了一个volatile int state变量,表示同步状态:当线程调用lock方法时,如果state=0,说明没有任何线程占有共享资源的锁,可以获得锁并将state=1;如果state=1,则说明有线程目前正在使用共享变量,其他线程必须加入同步队列进行等待。

2.AOS通过Node内部类构成的一个双向链表结构的同步队列,来完成线程获取锁的排队工作,当有线程获取锁失败后,就被添加到队列未尾。Node类是对要访问同步代码的线程的封装,包含了线程本身及其状态叫waitstatus(有五种不同取值,分别表示是否被呾塞,是否等待唤醒,是否已经被取消等),每个Node结点关联其prev结点和next结点,方便线程释放锁后快速唤醒下一个在等待的线程,是一个FIFO的过程。Node类有两个常量,SHARED和EXCLUSIVE,分别代表共享模式和独占模式。所谓共享模式是一个锁允许多条线程同时操作(信号量Semaphore就是基AQS的共享模式实现的),独占模式是同一个时间段只能有一个线程对共享资源进行操作,多余的请求线程需要排队等待(如ReentranLock)。

3.AOS通过内部类ConditionObiect构建等待队列(可有多个,当Condition调用walt0万法后,线程将会加入等待以列中,而当Condition调用signa0万法后,线程将从等待队列转移动同步队列中进行锁竞争。

4.AQS和Condition各自维护了不同的队列,在使用Lock和Condition的时候,其实就是两个队列的互相移动。

三:Synchronized和ReentrantLock二者有什么区别 

ReentrantLock是Lock的实现类,是一个互斥的同步锁。
从功能角度,Reentrantlock比synchronized的同步操作更精细(因为可以像普通对象一样使用),甚至实现Synchronized没有的高级功能

1.等待可中断:当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,对处理执行时间非常长的同步块很有用。口带超时的获取钡尝试。
在指定的时间范围内获取锁,如果时间到了仍然无法获取则返回。

2.可以判断是否有线程在排队等待获取锁。3.可以响应中断清求:与Synchronized不同,当获取到锁的线程被中断时,能够响应中断,中断异常将会被抛出,同时锁会被释放。4.可以实现公平锁。从锁释放角度,Synchronized在IVM层面上实现的,不但可以通过一些监控工具监控Synchronized的锁定,而且在代码执行出现异常
时,JVM会自动释放锁定;
但是使用Lock则不行,Lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally中。从性能角度,Synchronized早期实现比较低效,对比ReentrantLock,大多数场景性能都相差较大。但是在Java6中对其进行了非常多的改进,在竞争不激烈时,Svnchronized的性能要优于ReetrantLock:在高竞争情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态。

四:ReentrantLock是如何实现可重入锁的

Reentrant Lock内部自定义了同步器Sync(Sync既实现了AQS,又实现了AOS,而AOS提供了一种互斥锁持有的方式)
其实就是加锁的时候通过CAS算法,将线程对象放到一个双向链表中,每次获取锁的时候,看下当前维护的那个线程ID和当前请求的线程ID是否一样一样就可重入 

五:JUC还有哪些其他的并发工具

同步器:
提供了CountDownLatch、CycicBarrier、Semaphore等,比Synchronized更加高级,可以实现更加丰富多线程操作的同步结构。

容器:
提供了ConcurrentHashMap、有序的ConcunrrentskipListMap,或者通过类似快照机制实现线程安全的动态数组CopyOnWriteArayList等,各种线程安全的容器。

并发队列:
提供了ArrayBlockingQueue、synchorousQueue或针对特定场景的PriorityBlockingQueue等,各种并发队列实现

Executor框架
可以创建各种不同类型的线程池,调度任务运行等

六:JUC中的同步器有哪些

 JUC中的同步器三个主要的成员:CountDownLatch、CyclicBarrier和Semaphore,通过它们可以方便地实现很多线程之间协作的功能。CountDownLatch叫倒计数,允许一个或多个线程等待某些操作完成。看几个场景:
模拟并发,我需要启动100个线程去同时访问某一个地址,我希望它们能同时并发,而不是一个一个的去执行。
用法:CountDownLatch构造方法指明计数数量,被等待线程调用countDown将计数器减1,等待线程使用await进行线程等待。

CyclicBarrier叫循环栅栏,它实现让一组线程等待至某个状态之后再全部同时执行,而且当所有等待线程被释放后,CyclicBarier可以被重复使用。CyclicBarier的典型应用场景是用来等待并发线程结束,CyclicBarier的主要方法是await(0,await0每被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此CyclicBarier上面阻塞的线程开始运行。在这之后,如果再次调用await0,计数就又会变成N-1,新一轮重新开始,这便是Cyclic的含义所在。CyclicBarrier.await0)带有返回值,用来表示当前线程是第几个到达这个Barrier的线程,

Semaphore,ava版本的信号量实现,用于控制同时访问的线程个数,来达到限制涌用资源访问的日的,其原理是涌过acquire0获取一个许可,如果没有就等待,而release0释放一个许可。如果Semaphore的数值被初始化为1,那么一个线程就可以通过acquire进入豆斥状态,本质上和互斥锁是非常相似的。

但是区别也非常明显,比如互斥锁是有持有者的,而对于Semaphore这种计数器结构,虽然有类似功能,但其实不存在真正意义的持有者,除非我们进行扩展包装。

七:CountDownLatch和CyclicBarrier有什么区别

它们的行为有一定相似度,区别主要在于
1.CountDownLatch是不可以重置的,所以无法重用,CyclicBarrier没有这种限制,可以重用
2.CountDownLatch的基本操作组合是countDown/await,调用await的线程阻塞等待countDown足够的次数,不管你是在一个线程还是多个线程里countDown,只要次数足够即可,
CyclicBarrier的基本操作组合就是await,当所有的伙伴都调用了await,才会继续进行任务,并自动进行重置。CountDownLatch目的是让一个线程等待基他N个线程达到某个条件后,自己再去做某个事(通过CvcicBarier的第二个构造方法publicCyclicBarrier(intparties,RunnablebarrierAction),在新线程里做事可以达到同样的效果)而CycicBarier的目的是让N多线程互相等待直到所有的都达到某个状态,然后这N个线程再继续执行各自后续(通过CountDownlatch在某些场合也能完成类似的效果) 

这篇关于ReentrantLock可重入锁又是怎么回事?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1115044

相关文章

可重入锁和不可重入锁概念和区别

可重入锁就是一个类的A、B两个方法,A、B都有获得统一把锁,当A方法调用时,获得锁,在A方法的锁还没有被释放时,调用B方法时,B方法也获得该锁。 这种情景,可以是不同的线程分别调用这个两个方法。也可是同一个线程,A方法中调用B方法,这个线程调用A方法。 不可重入锁就是一个类的A、B两个方法,A、B都有获得统一把锁,当A方法调用时,获得锁,在A方法的锁还没有被释放时,调用B方法时,B方法也获得不

java线程 yield,sleep,join,synchronized wait notify notifyAll,ReentrantLock lock condition, 生产者消费者

yield,sleep,join yield,join,sleep,join是Thread中的方法,不需要 在synchronized 代码块中调用,和synchronized 没关系,也不会释放锁。 Thread.sleep(100);Thread.yield();Thread t;t.join(); (1)yield()不一定保证让出cpu yield()只是使当前线程重新回

synchronized wait()/notify 对比 ReentrantLock await()/signal()

结论 synchronized synchronized 配合 wait()/notify 无法实现精准唤醒线程 ReentrantLock ReentrantLock 配合 Condition await()/signal() 可以实现精准唤醒线程 (指唤醒指定的线程) ReentrantLock 如何实现精准唤醒线程 一个 lock 配合多个 Condition, 且

ReentrantLock的lockInterruptibly()理解

ReentrantLock锁有几种:lock、tryLock、tryLock(long timeout, TimeUnit unit)、lockInterruptibly。 lock 阻塞等待获取锁,优先考虑获取锁,待获取锁成功后,才响应中断。 lockInterruptibly 优先考虑响应中断,而不是响应锁的普通获取或重入获取。  tryLock() 是一个有返回值的方法,试图申请一个锁

【并发】Lock与ReentrantLock

1 Lock基本使用 Lock能实现代码同步,它比synchronized更具灵活性,什么时候锁住,什么时候释放锁等都是看得见的,使用时必须使用try{}finally{},意思是万一发生异常或者错误都可以释放锁。 try{}finally{//释放锁} 使用示例 public class SaleTicket implements Runnable {private int tic

可重入VI,VI模板和动态VI之间的差异 转

可重入VI 当您想要同时运行同一VI的多个实例时,将使用可重入VI。当VI不可重入时,VI只有一个数据空间。因此,一次只能有一个调用者运行VI,因此调用者可能必须“等待轮到它”时才能使用VI。这是VI的默认选项,但您可以将VI设置为可重入。其中有两种类型的重入:共享 和 预分配。 共享的可重入VI 如果选择了共享克隆可重入执行选项,则VI会具有一个数据空间池(与克隆池相同)。最初在调用VI开始时

多线程篇(基本认识 - 公平锁 非公平锁、独占锁 共享锁、可重入锁、自旋锁)(持续更新迭代)

目录 锁一:公平锁与非公平锁 前言 一、Lock 锁接口 二、公平锁 1. 简介 三、非公平锁 1. 简介 四、JUC 1. ReentranLock 公平锁 非公平锁 锁二:独占锁 & 共享锁 前言 一、简介 二、代码示例 1. 未加锁状态 2. 加锁状态 锁三:可重入锁 前言 一、简介 二、代码示例 锁四:自旋锁 一、前言 二、问题思考 三、思

Java并发之ReentrantLock详解

原文: http://blog.csdn.net/lipeng_bigdata/article/details/52154637      一、入题         ReentrantLock是Java并发包中互斥锁,它有公平锁和非公平锁两种实现方式,以lock()为例,其使用方式为: [java] view plain copy ReentrantLoc

msvcp120.dll丢失是怎么回事?几种靠谱修复msvcp120.dll的方法

在使用基于Windows的计算机进行日常工作或娱乐时,您可能会遇到一个错误消息:“无法启动此程序,因为计算机中丢失msvcp120.dll。”这样的提示通常在尝试启动某些程序或游戏时弹出,导致应用无法正常运行。这个问题通常与系统中的某个重要文件——msvcp120.dll有关,这是一个关键的系统文件,属于Microsoft Visual C++ 2013 Redistributable包的一部分。

除了Synchronized和ReentrantLock外,有哪些别的同步机制

除了synchronized和ReentrantLock外,有哪些别的同步机制 答案: Java提供了多种同步机制和锁用来满足不同的并发需求。除synchronized和ReentrantLock之外,还有以下几种: 1. CountDownLatch(倒计时器):允许一个或多个线程等待其他线程完成操作。它维护了一个计数器,表示需要等待的事件数量。每当一个事件完成时,计数器减一。 当计数器