概述

  为了对共享资源提供更细粒度的同步控制,JDK5新增了java.util.concurrent(JUC)并发工具包,并发包新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字相似的同步功能,只是在使用时需要显式地获取和释放锁,还具备内置锁不具备的自由操作锁获取和释放、可中断地获取锁以及超时获取锁等多种synchronized关键字不具备的同步特性。
  为了实现JUC提出的各种功能的锁,JUC包的作者,并发大师Doug Lee提出了同步器 synchronizer的概念,在同步器中定义了共享资源的同步状态,维护了一个双端的先入先出的同步队列用于存放获取共享资源失败而等待的线程,线程利用同步器实现的锁获取共享资源流程如下:

为了实现上述操作,需要下面三个基本组件的相互协作:

  • 对共享资源同步状态进行原子性管理 ---> 利用CAS对同步状态进行更新
  • 线程的阻塞与唤醒 ---> 调用native方法
  • 等待队列的管理 ---> 维护FIFO队列

  由此可以看出,同步器是实现锁的关键,同步器面向的是线程访问和资源控制,它定义了线程对资源是否能够获取以及线程的排队等操作。关于同步器的详细解释会在AQS(AbstractQueuedSynchronizer)解析里给出。

JUC锁框架图

  JUC中Lock接口定义了锁的规范,各种功能的锁都实现了Lock接口,各个锁以内部类继承AQS同步器的方式聚合了同步器,从而以同步器为基石实现具体功能的锁。

  1. Lock
      Lock接口为独占锁(同一时间共享资源只能由一个线程获取),共享锁(同一时间共享资源可由多个线程获取),公平锁(各个线程获得锁的机会是公平的),非公平锁(各个线程获得锁的机会是公平的),重入锁(线程在获取到锁之后,再次获取该锁而不会被该锁所阻塞,不会自己把自己锁在外面)提供了实现规范,接口中定义的方法如下:

  2. AbstractQueuedSynchronizer
      AbstractQueuedSynchronizer就是被称之为AQS的类,可以用于构建锁或者其他相关同步装置的基础框架。从图中也可以看出,ReentrantLock,ReentrantReadWriteLock,CountDownLatch,CyclicBarrier和Semaphore这些类通过内部类继承AQS的方式来实现锁的功能。

  3. Condition
      Condition需要和Lock联合使用,它的作用是代替Object监视器方法,可以通过await(),signal()来休眠/唤醒线程。Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的功能,接口中定义的方法如下:

  4. LockSurport
      LockSupport中的park() 和 unpark()调用native方法将线程休眠。

  5. ReentrantLock
      ReentrantLock对与共享资源采取的是较为保守的独占策略,即只有一个线程能够获得锁;ReentrantLock支持公平锁和非公平锁,默认是非公平锁;从名称也能看出,ReentrantLock是可重入锁。

  6. ReentrantReadWriteLock
      ReentrantReadWriteLock是读写锁接口ReadWriteLock的实现类,它包括子类ReadLock和WriteLock。ReentrantLock是共享锁,而WriteLock是独占锁。

  7. CountDownLatch
      CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

  8. CyclicBarrier
      CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点(common barrier point)。因为该barrier在释放等待线程后可以重用,所以称它为循环的barrier。

  9. Semaphore
      Semaphore是一个计数信号量,它的本质是一个"共享锁"。信号量维护了一个信号量许可集。线程可以通过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。

使用内置锁还是JUC显示锁?

  JUC中的显示锁提供了与synchronized内置锁相同的互斥性与内存可见性,那么我们的多线程代码到底使用哪一种锁来实现同步呢?首先从性能角度考虑,在JDK5 显示锁刚推出时,性能是大幅领先于内置锁的,在随后的JDK版本中,JVM对内置锁进行了性能优化,现在二者的性能已经没有明显优劣之分;从功能使用上,内置锁的使用较为简单,无需手动获得以及释放锁,而显示锁的功能更为强大,具有更高的灵活性,当我们需要使用到锁的高级功能,如以响应中断/支持超时的方式获取锁或者自定义实现锁,这时候可以考虑内置锁。

多线程学习笔记二之JUC组件的更多相关文章

  1. 多线程学习笔记(二) BackgroundWorker 和 ProgressChanged

    BackgroundWorker是在内部使用了线程池的技术:同时,在Winform 或WPF编码中,它还给工作线程和UI线程提供了交互的能力. Thread和ThreadPool默认都没有提供这种交互 ...

  2. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  3. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  4. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  5. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

  6. muduo学习笔记(二)Reactor关键结构

    目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...

  7. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  8. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  9. java进阶-多线程学习笔记

    多线程学习笔记 1.什么是线程 操作系统中 打开一个程序就是一个进程 一个进程可以创建多个线程 现在系统中 系统调度的最小单元是线程 2.多线程有什么用? 发挥多核CPU的优势 如果使用多线程 将计算 ...

随机推荐

  1. 用HashSet存储不重复的对象

    直接进入主题,先来创建一个类:Bean public class Bean { private int id; private String name; public Bean() { super() ...

  2. CGI浏览器与服务器的交互

    一直在做项目,跟着写前端后端,却没有思考一个问题:前端和后端为什么能够进行通信?为什么能够将HTML页面的内容传输给后台,然后又将结果反馈给前端? 寒假偶尔看到了这个问题,也解决了我的疑惑,这是基于C ...

  3. UDP ------ UDP打洞

    为什么需要UDP打洞 处于两个不同局域网的主机不能直接进行UDP通信 UDP"打洞"原理 1.       NAT分类 根据Stun协议(RFC3489),NAT大致分为下面四类 ...

  4. MySQL事务及隔离级别详解

    MySQL事务及隔离级别详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的基本架构 MySQL的基本架构可以分为三块,即连接池,核心功能层,存储引擎层. 1> ...

  5. 在angular中利用分页插件进行分页

    必需:angular分页js和css  当然还有angular.js   还需要bootstrap的css angular.min.js (下面我直接把插件粘贴上去了,以免有的同学还要去找.是不是很贴 ...

  6. bzoj千题计划262:bzoj4868: [六省联考2017]期末考试

    http://www.lydsy.com/JudgeOnline/problem.php?id=4868 假设 最晚出成绩的是第i天 预处理 cnt[i] 表示 有多少个学生 期望出成绩的那一天 &l ...

  7. 何凯文每日一句打卡||DAY9

  8. NAT地址转换

    2017年1月12日, 星期四 NAT地址转换 SNAT:源地址转换  DNAT:目标地址转换   null

  9. JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系

    一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...

  10. RabbitMq简单应用

    服务端: <?php //配置信息 $conn_args = array( 'host' => '127.0.0.1', 'port' => '5672', 'login' => ...