并发编程-ReentrantLock 细节说明

---
title: 并发编程-ReentrantLock 细节说明
date: 2018-07-05 09:06:57
categories:
- 并发编程
---

<Excerpt in index | 首页摘要>
<!-- more -->

- 本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:
- ReentrantLock介绍
- ReentrantLock函数列表
- ReentrantLock示例

<The rest of contents | 余下全文>

并发编程-ReentrantLock介绍 细节说明

1. ReentrantLock-是一个可重入的互斥锁,又被称为“独占锁”

* ReentrantLock
* ReentrantLock锁在同一个时间点只能被一个线程锁持有;而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取。
* ReentrantLock分为“公平锁”和“非公平锁”。它们的区别体现在获取锁的机制上是否公平。“锁”是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在同一个时间点只能被一个线程获取(当某线程获取到“锁”时,其它线程就必须等待);ReentraantLock是通过一个FIFO的等待队列来管理获取该锁所有线程的。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。
- [x] ReentrantLock 类方法简介

  1. // 创建一个 ReentrantLock ,默认是“非公平锁”。
  2. ReentrantLock()
  3. // 创建策略是fair的 ReentrantLock。fair为true表示是公平锁,fair为false表示是非公平锁。
  4. ReentrantLock(boolean fair)
  5.  
  6. // 查询当前线程保持此锁的次数。
  7. int getHoldCount()
  8. // 返回目前拥有此锁的线程,如果此锁不被任何线程拥有,则返回 null。
  9. protected Thread getOwner()
  10. // 返回一个 collection,它包含可能正等待获取此锁的线程。
  11. protected Collection<Thread> getQueuedThreads()
  12. // 返回正等待获取此锁的线程估计数。
  13. int getQueueLength()
  14. // 返回一个 collection,它包含可能正在等待与此锁相关给定条件的那些线程。
  15. protected Collection<Thread> getWaitingThreads(Condition condition)
  16. // 返回等待与此锁相关的给定条件的线程估计数。
  17. int getWaitQueueLength(Condition condition)
  18. // 查询给定线程是否正在等待获取此锁。
  19. boolean hasQueuedThread(Thread thread)
  20. // 查询是否有些线程正在等待获取此锁。
  21. boolean hasQueuedThreads()
  22. // 查询是否有些线程正在等待与此锁有关的给定条件。
  23. boolean hasWaiters(Condition condition)
  24. // 如果是“公平锁”返回true,否则返回false。
  25. boolean isFair()
  26. // 查询当前线程是否保持此锁。
  27. boolean isHeldByCurrentThread()
  28. // 查询此锁是否由任意线程保持。
  29. boolean isLocked()
  30. // 获取锁。
  31. void lock()
  32. // 如果当前线程未被中断,则获取锁。
  33. void lockInterruptibly()
  34. // 返回用来与此 Lock 实例一起使用的 Condition 实例。
  35. Condition newCondition()
  36. // 仅在调用时锁未被另一个线程保持的情况下,才获取该锁。
  37. boolean tryLock()
  38. // 如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁。
  39. boolean tryLock(long timeout, TimeUnit unit)
  40. // 试图释放此锁。
  41. void unlock()

2. ReentrantLock-示例 说明

* lock和unlock的作用

  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantLock;
  3.  
  4. // LockTest1.java
  5. // 仓库
  6. class Depot {
  7. private int size; // 仓库的实际数量
  8. private Lock lock; // 独占锁
  9.  
  10. public Depot() {
  11. this.size = 0;
  12. this.lock = new ReentrantLock();
  13. }
  14.  
  15. public void produce(int val) {
  16. lock.lock();
  17. try {
  18. size += val;
  19. System.out.printf("%s produce(%d) --> size=%d\n",
  20. Thread.currentThread().getName(), val, size);
  21. } finally {
  22. lock.unlock();
  23. }
  24. }
  25.  
  26. public void consume(int val) {
  27. lock.lock();
  28. try {
  29. size -= val;
  30. System.out.printf("%s consume(%d) <-- size=%d\n",
  31. Thread.currentThread().getName(), val, size);
  32. } finally {
  33. lock.unlock();
  34. }
  35. }
  36. };
  37.  
  38. // 生产者
  39. class Producer {
  40. private Depot depot;
  41.  
  42. public Producer(Depot depot) {
  43. this.depot = depot;
  44. }
  45.  
  46. // 消费产品:新建一个线程向仓库中生产产品。
  47. public void produce(final int val) {
  48. new Thread() {
  49. public void run() {
  50. depot.produce(val);
  51. }
  52. }.start();
  53. }
  54. }
  55.  
  56. // 消费者
  57. class Customer {
  58. private Depot depot;
  59.  
  60. public Customer(Depot depot) {
  61. this.depot = depot;
  62. }
  63.  
  64. // 消费产品:新建一个线程从仓库中消费产品。
  65. public void consume(final int val) {
  66. new Thread() {
  67. public void run() {
  68. depot.consume(val);
  69. }
  70. }.start();
  71. }
  72. }
  73.  
  74. public class LockTest1 {
  75. public static void main(String[] args) {
  76. Depot mDepot = new Depot();
  77. Producer mPro = new Producer(mDepot);
  78. Customer mCus = new Customer(mDepot);
  79.  
  80. mPro.produce(60);
  81. mPro.produce(120);
  82. mCus.consume(90);
  83. mCus.consume(150);
  84. mPro.produce(110);
  85. }
  86. }

运行结果

  1. Thread-0 produce( 60) --> left= 0, inc= 60, size= 60
  2. Thread-1 produce(120) --> left= 80, inc= 40, size=100
  3. Thread-2 consume( 90) <-- left= 0, dec= 90, size= 10
  4. Thread-3 consume(150) <-- left=140, dec= 10, size= 0
  5. Thread-4 produce(110) --> left= 10, inc=100, size=100
  6. Thread-3 consume(150) <-- left= 40, dec=100, size= 0
  7. Thread-4 produce(110) --> left= 0, inc= 10, size= 10
  8. Thread-3 consume(150) <-- left= 30, dec= 10, size= 0
  9. Thread-1 produce(120) --> left= 0, inc= 80, size= 80
  10. Thread-3 consume(150) <-- left= 0, dec= 30, size= 50

  

3.并发编程-ReentrantLock 细节说明的更多相关文章

  1. 5.并发编程-synchronized 细节说明

    并发编程-synchronized 细节说明 1. synchronized-锁重入 & 异常释放锁 说明 * 关键字synchronized 拥有锁重入的功能,也就是在使用synchroni ...

  2. Java并发编程-ReentrantLock

    代码示例: Lock lock = new ReentrantLock(); lock.lock(); try { // update object state } finally { lock.un ...

  3. Java并发编程-ReentrantLock源码分析

    一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...

  4. Java并发编程 ReentrantLock 源码分析

    ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...

  5. 并发编程实践五:ReentrantLock

    ReentrantLock是一个可重入的相互排斥锁,实现了接口Lock,和synchronized相比,它们提供了同样的功能.但ReentrantLock使用更灵活.功能更强大,也更复杂.这篇文章将为 ...

  6. java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock

    原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...

  7. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析

    前篇博客LZ已经分析了ReentrantLock的lock()实现过程,我们了解到lock实现机制有公平锁和非公平锁,两者的主要区别在于公平锁要按照CLH队列等待获取锁,而非公平锁无视CLH队列直接获 ...

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介

    注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...

  9. Java并发编程总结3——AQS、ReentrantLock、ReentrantReadWriteLock(转)

    本文内容主要总结自<Java并发编程的艺术>第5章——Java中的锁. 一.AQS AbstractQueuedSynchronizer(简称AQS),队列同步器,是用来构建锁或者其他同步 ...

随机推荐

  1. queue的常见用法

    queue的使用 queue是什么? queue是一种先入先出的容器 queue的定义 引入 # include <iostream> # include <queue> us ...

  2. 断言(assert)

    断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言. 简单点说,断言指的就是,将结果判断说 ...

  3. Linux FTP的安装与权限配置

    ftp安装部分,操作步骤如下: 1.切换到root用户 2.查看是否安装vsftp,我这个是已经安装的. [root@localhost vsftpd]# rpm -qa |grep vsftpd v ...

  4. 修改jar包package目录结构操作方法

    开发中会遇到用第三方的jar包,有时候会出现不同的jar包,包名一致的情况,这就会引发运行时异常,找不到相应的jar包. 这种问题时常困扰我们很长时间.下面提出一种解决办法,例如gson.jar. 1 ...

  5. vue 简介 vue 项目 组件

    1. 概念 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.能够为复杂的单页应用提供驱动. 2. 用法 2.1 声明式渲染 2.1.1 改变文本     {{ m ...

  6. k8s+docker+proget 镜像制作

    安装proget 1 首先在k8s上运行proget的数据库配置有个注意点:要根据proget官网要求的sql server排序方式建数据库,不然数据保存的时候会报错 2 proget运行起来后,默认 ...

  7. GitHub源码攻击事件

    黑客擦除了微软多达392个代码存储库,并提出勒索要求.此前,黑客攻击了包含微软在内的大批受害者的Git存储库,删除了所有源代码和最近提交的内容,并留下了支持比特币支付的赎金票据. 勒索信息如下: “要 ...

  8. RHEL6 中/etc/fstab文件解析

    1.系统环境 [root@natsha ~]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 6.5 (Santiag ...

  9. Hive的架构(二)

    02 Hive的架构 1.Hive的架构图 2.Hive的服务(角色) 1.用户访问接口 ​ CLI(Command Line Interface):用户可以使用Hive自带的命令行接口执行Hive ...

  10. Codeforces1223E. Paint the Tree(树形dp)

    题目链接:传送门 题目大意: 给出节点数为n的一棵带权树,和每个点的最大染色数k.一条边的权重w能产生价值w的条件是,这条边的两端的点至少有一个颜色相同.颜色种类数无限,但每种只能使用两次,问能产生的 ...