Java多线程:“JUC锁”03之公平锁(一)

基本概念

本章,我们会讲解“线程获取公平锁”的原理;在讲解之前,需要了解几个基本概念。后 面的内容,都是基于这些概念的;这些概念可能比较枯燥,但从这些概念中,能窥见“java锁 ”的一些架构,这对我们了解锁是有帮助的。

1. AQS        -- 指AbstractQueuedSynchronizer类。

AQS 是java中管理“锁”的抽象类,锁的许多公共方法都是在这个类中实现。AQS是独占锁(例如, ReentrantLock)和共享锁(例如,Semaphore)的公共父类。

2. AQS锁的类别 -- 分为“独占锁”和 “共享锁”两种。

(01) 独占锁 -- 锁在一个时间点 只能被一个线程锁占有。根据锁的获取机制,它又划分为“公平锁”和 “非公平锁”。公平锁,是按照通过CLH等待线程按照先来先得的规则,公 平的获取锁;而非公平锁,则当线程要获取锁时,它会无视CLH等待队列而直接获取锁。独占锁的典型实 例子是ReentrantLock,此外,ReentrantReadWriteLock.WriteLock也是独占锁。

(02) 共享 锁 -- 能被多个线程同时拥有,能被共享的锁。JUC包中的ReentrantReadWriteLock.ReadLock ,CyclicBarrier, CountDownLatch和Semaphore都是共享锁。这些锁的用途和原理,在以后的章节再详 细介绍。

3. CLH队列     -- Craig, Landin, and Hagersten lock queue

CLH队列是AQS中“等待锁”的线程队列。在多线程中,为了保护竞争资源不被多个线 程同时操作而起来错误,我们常常需要通过锁来保护这些资源。在独占锁中,竞争资源在一个时间点只能 被一个线程锁访问;而其它线程则需要等待。CLH就是管理这些“等待锁”的线程的队列。

CLH是一个非阻塞的 FIFO 队列。也就是说往里面插入或移除一个节点的时候,在并发条件下不会阻塞 ,而是通过自旋锁和 CAS 保证节点插入和移除的原子性。

4. CAS函数     -- Compare And Swap

CAS函数,是比较并交换函 数,它是原子操作函数;即,通过CAS操作的数据都是以原子方式进行的。例如, compareAndSetHead(), compareAndSetTail(), compareAndSetNext()等函数。它们共同的特点是,这些 函数所执行的动作是以原子的方式进行的。

本章是围绕“公平锁”如何获取锁而层次展开。“公平锁”涉及到的知识点比 较多,但总的来说,不是特别难;如果读者能读懂AQS和ReentrantLock.java这两个类的大致意思,理解 锁的原理和机制也就不成问题了。本章只是作者本人对锁的一点点理解,希望这部分知识能帮助您了解 “公平锁”的获取过程,认识“锁”的框架。

ReentrantLock数据结构

ReentrantLock的UML类图

从图中可以看出:

(01) ReentrantLock实现了Lock接口。

(02) ReentrantLock与sync是组合关系。ReentrantLock中,包含了Sync对象;而且,Sync是AQS的子类; 更重要的是,Sync有两个子类FairSync(公平锁)和NonFairSync(非公平锁)。ReentrantLock是一个独占锁 ,至于它到底是公平锁还是非公平锁,就取决于sync对象是"FairSync的实例"还是 "NonFairSync的实例"。

时间: 2024-10-02 22:54:28

Java多线程:“JUC锁”03之公平锁(一)的相关文章

Java多线程:“JUC锁”04之公平锁(二)

概要 前面一章,我们学习了"公平锁"获取锁的详细流程:这里,我们再来看看"公平锁 "释放锁的过程.内容包括: 参考代码 释放公平锁(基于JDK1.7.0_40) "公平锁"的获取过程请参考"Java多线程系列--"JUC锁"03之 公平锁 (一)",锁的使用示例请参考"Java多线程系列--"JUC锁"02之 互斥锁 ReentrantLock". 注意: (01)

Java多线程的同步示例及对象锁机制

java多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问. 下面以一个简单的实例来进行对比分析.实例要完成的工作非常简单,就是创建10个线程,每个线程都打印从0到99这100个数字,我们希望线程之间不会出现交叉乱序打印,而是顺序地打印. 先来看第一段代码,这里我们在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问,但结果并不如我们希望那样,这 是因为这里synchronized锁住的是this对象,即

Java多线程:“JUC锁”02之互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是, ReentrantLock锁,可以被单个线程多次获取. ReentrantLock分为"公平锁"和"非 公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源, 防止多个线程同时操作线程而出错,ReentrantL

详解Java多线程编程中互斥锁ReentrantLock类的用法_java

0.关于互斥锁 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronized机制更广泛的锁定操作, Lock和synchronized机制的主要区别: synchronized机制提供了对与每个对象相关的隐式监视器锁的访问, 并强制所有锁获取和释放均要出现在一个块结构中, 当获取了多个锁时, 它们必须以相反的顺序释放. synchronized机制对锁的释放是

java多线程之:深入JVM锁机制2-Lock (转载)

前文(深入JVM锁机制-synchronized)分析了JVM中的synchronized实现,本文继续分析JVM中的另一种锁Lock的实现.与synchronized不同的是,Lock完全用Java写成,在java这个层面是无关JVM实现的. 在 java.util.concurrent.locks包中有很多Lock的实现类,常用的有ReentrantLock. ReadWriteLock(实现类ReentrantReadWriteLock),其实现都依赖 java.util.concurre

[Java] 多线程下生产者消费者问题的五种同步方法实现

版权声明:请尊重个人劳动成果,转载注明出处,谢谢! 目录(?)[+] 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.    生产者消费者模式的优点 - 解耦 - 支持并发 - 支持忙闲不均 解决方法可分为两类:   (1)用信号量和锁机制实现生产者和消费者之间的同步:    - wait() / notify()方法  - await() / signal()方法  - BlockingQueue阻塞队列方法  - Semaphore方法    (2)在生产者和消费者之间建立一

Java多线程知识小抄集(三)

本文主要整理博主遇到的Java多线程的相关知识点,适合速记,故命名为"小抄集".本文没有特别重点,每一项针对一个多线程知识做一个概要性总结,也有一些会带一点例子,习题方便理解和记忆. 51. SimpleDateFormat非线程安全 当多个线程共享一个SimpleDateFormat实例的时候,就会出现难以预料的异常. 主要原因是parse()方法使用calendar来生成返回的Date实例,而每次parse之前,都会把calendar里的相关属性清除掉.问题是这个calendar是

《Java多线程编程核心技术》——导读

前 言为什么要写这本书早在几年前笔者就曾想过整理一份与Java多线程有关的稿件,因为市面上所有的Java书籍都是以一章或两章的篇幅介绍多线程技术,并没有完整地覆盖该技术的知识点,但可惜,苦于当时的时间及精力有限,一直没有达成所愿.也许是注定的安排,我目前所在的单位是集技术与教育为一体的软件类企业.我在工作中发现很多学员在学习完JavaSE/JavaEE之后想对更深入的技术进行探索,比如在对大数据.分布式.高并发类的专题进行攻克时,立即遇到针对java.lang包中Thread类的学习,但Thre

java多线程:synchronized和lock比较浅析

转载:http://www.toutiao.com/a6392135944652587266/?tt_from=weixin&utm_campaign=client_share&app=news_article&utm_source=weixin&iid=7704173001&utm_medium=toutiao_ios&wxshare_count=1     synchronized是基于jvm底层实现的数据同步,lock是基于Java编写,主要通过硬件依