ReentrantLock 实现原理
时间:2020-04-16
本文章向大家介绍ReentrantLock 实现原理,主要包括ReentrantLock 实现原理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
使用 synchronized
来做同步处理时,锁的获取和释放都是隐式的,实现的原理是通过编译后加上不同的机器指令来实现。
而 ReentrantLock
就是一个普通的类,它是基于 AQS(AbstractQueuedSynchronizer)
来实现的。
是一个重入锁:一个线程获得了锁之后仍然可以反复的加锁,不会出现自己阻塞自己的情况。
锁类型
ReentrantLock 分为公平锁和非公平锁,可以通过构造方法来指定具体类型:
1 //默认非公平锁(默认一般都是非公平锁) 2 public ReentrantLock() { 3 sync = new NonfairSync(); 4 } 5 6 //公平锁 7 public ReentrantLock(boolean fair) { 8 sync = fair ? new FairSync() : new NonfairSync(); 9 }
获取锁
1 private ReentrantLock lock = new ReentrantLock(); 2 public void run() { 3 lock.lock(); 4 try { 5 //do bussiness 6 } catch (InterruptedException e) { 7 e.printStackTrace(); 8 } finally { 9 lock.unlock(); 10 } 11 }
释放锁
公平锁和非公平锁的释放流程都是一样的:
1 public void unlock() { 2 sync.release(1); 3 } 4 5 public final boolean release(int arg) { 6 if (tryRelease(arg)) { 7 Node h = head; 8 if (h != null && h.waitStatus != 0) 9 //唤醒被挂起的线程 10 unparkSuccessor(h); 11 return true; 12 } 13 return false; 14 } 15 16 //尝试释放锁 17 protected final boolean tryRelease(int releases) { 18 int c = getState() - releases; 19 if (Thread.currentThread() != getExclusiveOwnerThread()) 20 throw new IllegalMonitorStateException(); 21 boolean free = false; 22 if (c == 0) { 23 free = true; 24 setExclusiveOwnerThread(null); 25 } 26 setState(c); 27 return free; 28 }
首先会判断当前线程是否为获得锁的线程,由于是重入锁所以需要将 state
减到 0 才认为完全释放锁。
释放之后需要调用 unparkSuccessor(h)
来唤醒被挂起的线程。
原文地址:https://www.cnblogs.com/seedss/p/12713706.html
- 使用Donut Caching和Donut Hole Caching在ASP.NET MVC应用中缓存页面何时使用Donut CachingDonut Caching 的Nuget 包Donut Ho
- 有趣的算法(九) ——蛇形数组
- 有趣的算法(十一) ——分治法:快速求最值
- ASP.NET AJAX(3)__UpdatePanel
- 正则表达式学习笔记
- PHP10个实用函数
- ASP.NET AJAX(2)__ASP.NET 2.0 AJAX Extensions
- Android利用V4包中的SwipeRefreshLayout实现上拉加载
- 在Scala项目中使用Spring Cloud
- Scala的面向对象与函数编程
- ASP.NET AJAX(1)__Microsoft AJAX LibraryASP.NET AJAX(1)__Microsoft AJAX Library
- 大数据流处理平台的技术选型参考
- PHP预定义变量数组种类概览
- PHP网络技术(二)——模拟网络灌水攻防
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 非易失性WAL buffer实现解析(三)
- android实现切换日期左右无限滑动效果
- 疯子的算法总结(七) 字符串算法之 manacher 算法 O(N)解决回文串
- PostgreSQL WAL解析:构建WAL记录准备
- CodeForces - 225C. Barcode(DP)
- android studio 3.0 service项目背景音乐实现
- 疯子的算法总结(六) 复杂排序算法 ① 归并排序 merge_sort()
- PostgreSQL扫描方法综述
- CodeForces - 224C. Bracket Sequence (栈模拟)简单做法
- XLOG段文件跳号现象分析
- codeforce 227E 矩阵快速幂求斐波那契+N个连续数求最大公约数+斐波那契数列的性质
- 疯子的算法总结(五) 矩阵乘法 (矩阵快速幂)
- codeforce 227D Naughty Stone Piles (贪心+递归+递推)
- POJ3614防晒霜 这个贪心有点东西(贪心+优先队列)
- 环形均分纸牌问题(中位数)