可重入锁指的是假设一个线程已经获得了一个锁,那么它能够多次进入这个锁,当然前提是线程须要先获得这个锁。

可重入锁是最常使用的锁。Java的内置锁就是可重入锁,使用synchronizedkeyword能够启用内置锁机制,比方说一个类有两个synchronized方法A和B。在A方法中调用了B方法,假设锁不是可重入的。那么訪问B时须要再次竞争锁。这样会带来死锁。

        public synchronized void A(){B();}public synchronized void B(){}

可重入锁攻克了这个问题,它使用一个计数器来记录一个线程进入锁的次数,每次进入锁计数器就加1。释放锁减1。直到计数器为0时表示真正释放了锁。其它锁看到计数器不为0时就知道有其它线程已经获得了锁。就须要等待。Java的内置锁的基本原理也是这样,JDK1.5之后提供了显式锁ReentrantLock也是这个基本原理。

以下实现一个简单的可重入锁。

1. 使用一个Thread引用指向获得锁的线程

2. 使用一个计数器记录一个线程进入锁的次数,当计数器为0时表示锁是空暇的

3. 使用一个内部锁Lock来同步线程

4. 使用一个isHoldZero的条件来进行条件队列操作

5. 当获得锁的线程是自己时,仅仅改动计数器的值,直接获得锁

6. 当获得锁的线程不是自己时。须要在holdCount !=0 这个条件谓词上等待。直到计数器归0,再次竞争锁

7. 释放锁时计数器减1,当计数器为0时。唤醒在条件队列中等待的线程

package com.zc.lock;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;/*** 简单的可重入锁实现,使用一个计数器记录当前线程重入锁的次数,获得锁时计数器加1,释放锁时计数器减1。当计数器等于0时表示释放了锁* **/
public class SimpleReentrantLock implements Lock{// 指向已经获得锁的线程private volatile Thread exclusiveOwnerThread;// 记录获取了同一个锁的次数private volatile int holdCount;private final java.util.concurrent.locks.Lock lock;// 是否是自己获得锁的条件private final Condition isCountZero;public SimpleReentrantLock(){lock = new ReentrantLock();isCountZero = lock.newCondition();holdCount = 0;}@Overridepublic void lock() {lock.lock();try{// 当前线程的引用Thread currentThread = Thread.currentThread();// 假设获得锁的线程是自己,那么计数器加1,直接返回if(exclusiveOwnerThread == currentThread){holdCount ++;return;}while(holdCount != 0){try {isCountZero.await();} catch (InterruptedException e) {throw new RuntimeException("Interrupted");}}// 将exclusiveOwnerThread设置为自己exclusiveOwnerThread = currentThread;holdCount ++;}finally{lock.unlock();}}@Overridepublic void unlock() {lock.lock();try{holdCount --;if(holdCount == 0){isCountZero.signalAll();}}finally{lock.unlock();}}}

转载于:https://www.cnblogs.com/gcczhongduan/p/5080648.html

聊聊高并发(十六)实现一个简单的可重入锁相关推荐

  1. 聊聊高并发(六)实现几种自旋锁

    这一篇我们通过两种实现自旋锁的方式来看一下不同的编程方式带来的程序性能的变化. 先理解一下什么是自旋,所谓自旋就是线程在不满足某种条件的情况下,一直循环做某个动作.所以对于自旋锁来锁,当线程在没有获取 ...

  2. 聊聊高并发(六)实现几种自旋锁(一)

    在聊聊高并发(五)理解缓存一致性协议以及对并发编程的影响 我们了解了处理器缓存一致性协议的原理,并且提到了它对并发编程的影响,"多个线程对同一个变量一直使用CAS操作,那么会有大量修改操作, ...

  3. 聊聊高并发(二十七)解析java.util.concurrent各个组件(九) 理解ReentrantLock可重入锁

    这篇讲讲ReentrantLock可重入锁,JUC里提供的可重入锁是基于AQS实现的阻塞式可重入锁.这篇 聊聊高并发(十六)实现一个简单的可重入锁 模拟了可重入锁的实现.可重入锁的特点是: 1. 是互 ...

  4. 第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁【Java面试题】

    第二季:5值传递和引用传递[Java面试题] 前言 推荐 值传递 说明 题目 24 TransferValue醒脑小练习 第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自 ...

  5. 聊聊高并发(三十六)Java内存模型那些事(四)理解Happens-before规则

    在前几篇将Java内存模型的那些事基本上把这个域底层的概念都解释清楚了,聊聊高并发(三十五)Java内存模型那些事(三)理解内存屏障 这篇分析了在X86平台下,volatile,synchronize ...

  6. 聊聊高并发(四十)解析java.util.concurrent各个组件(十六) ThreadPoolExecutor源码分析

    ThreadPoolExecutor是Executor执行框架最重要的一个实现类,提供了线程池管理和任务管理是两个最基本的能力.这篇通过分析ThreadPoolExecutor的源码来看看如何设计和实 ...

  7. 聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁

    这篇讲讲ReentrantReadWriteLock可重入读写锁,它不仅是读写锁的实现,并且支持可重入性. 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁) 这篇讲了如何模拟一个读写锁. 可重 ...

  8. 聊聊高并发(二十五)解析java.util.concurrent各个组件(七) 理解Semaphore

    前几篇分析了一下AQS的原理和实现,这篇拿Semaphore信号量做例子看看AQS实际是如何使用的. Semaphore表示了一种可以同时有多个线程进入临界区的同步器,它维护了一个状态表示可用的票据, ...

  9. 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁

    上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和主要的方法,显示了如何 ...

最新文章

  1. HDU2568 前进【水题】
  2. 【Python刷题】_2
  3. 我很明确自己未来的方向,计算机和经济外加管理
  4. RBAC模型:设计思路
  5. php判断秒为两位数,判“新”函数:得到今天与明天的秒数
  6. PHP 统计一个字符串,在另一个字符串中出现次数
  7. 向量化编程:arrayfun及cellfun函数的使用
  8. 微型计算机机房湿度不宜过大,全国计算机一级考试选择题试题与详细答案(免费)...
  9. 【黑苹果 Hackintosh】Delll成就5468(Vostro 5468)黑苹果
  10. 360,驱动精灵文件夹删除方法,解决管理员权限下仍无法删除的问题!
  11. c语言采用牛顿迭代法求解一元三次方程,使用牛顿迭代法求根 一元三次方程的根...
  12. 学习.NET ,提升.NET技能,这些公众号得关注
  13. vue 在线阅读PDF
  14. 曾经被微软视为毒瘤的“开源”,现在却成了“宠儿”
  15. 很好用的数据库数据字典【可导出为word , excel文件】
  16. 工具论-科学是实用工具
  17. 前置机应用服务器,web服务器前置机(erp)部署步骤.pdf
  18. 求矩阵A的转置矩阵B,其中Bij=Aji。
  19. 【Python军火库】pyautogui:成熟的鼠标和键盘自己动起来!
  20. 去掉Excel单元格最右边的几个字母

热门文章

  1. 将页面元素置为不可修改Readonly,所有元素统一修改,统一调用
  2. RabbitMQ 入门系列(4)— RabbitMQ 启动、停止节点和应用程序、用户管理、权限配置
  3. spring Ioc本质
  4. 难忘的一天——装操作系统(一)
  5. 【JavaWeb】servlet与http请求协议
  6. pytorch nn.Embedding
  7. python命令之m参数 局域网传输
  8. 王道考研 计算机网络笔记 第二章:物理层
  9. CPU,GPU,Memory调度
  10. TVM部署预定义模型