
java并发学习23:ReentrantLock介绍使用
发布日期:2021-05-07 02:04:34
浏览次数:17
分类:精选文章
本文共 3633 字,大约阅读时间需要 12 分钟。
1、与synchronized相比
- 可中断
- 可以设置超时时间
- 可以设置为公平锁
- 支持多个条件变量
与synchronized一样,都支持可重入
基本语法:
// 获取锁reentrantLock.lock();try { // 临界区} finally { // 释放锁 reentrantLock.unlock();}
2、可重入
可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获取这把锁
如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住
static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) { method1();}public static void method1() { lock.lock(); try { log.debug("execute method1"); method2(); } finally { lock.unlock(); }}public static void method2() { lock.lock(); try { log.debug("execute method2"); method3(); } finally { lock.unlock(); }}public static void method3() { lock.lock(); try { log.debug("execute method3"); } finally { lock.unlock(); }}
3、可打断
lock.lockInterruptibly();//获取锁,同时可以被其他线程打断
static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) { new Thread(() -> { method1(); },"t1")}public static void method1() { //如果没有竞争那么方法就会获取lock对象锁 //如果没有竞争就进入阻塞队列,可以被其他线程用interrupt 方法打断 lock.lockInterruptibly(); try { log.debug("execute method1"); method2(); } finally { lock.unlock(); }}
4、锁超时
4.1 立刻失败
ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> { log.debug("启动..."); if (!lock.tryLock()) { log.debug("获取立刻失败,返回"); return; } try { log.debug("获得了锁"); } finally { lock.unlock(); }}, "t1");lock.lock();log.debug("获得了锁")
4.2 超时失败
ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> { log.debug("启动..."); try { if (!lock.tryLock(1, TimeUnit.SECONDS)) { log.debug("获取等待 1s 后失败,返回"); return; } } catch (InterruptedExceptione) { e.printStackTrace(); } try { log.debug("获得了锁"); } finally { lock.unlock(); }}, "t1");lock.lock();log.debug("获得了锁");t1.start();try { sleep(2);} finally { lock.unlock();}
4.3tryLock解决哲学家问题
class Chopstick extends ReentrantLock { String name; public Chopstick(Stringname) { this.name=name; } @Override public String toString() { return"筷子{"+name+'}'; }}class Philosopher extends Thread { Chopstick left; Chopstick right; public Philosopher(Stringname, Chopstickleft, Chopstickright) { super(name); this.left=left; this.right=right; } @Override public void run() { while (true) { // 尝试获得左手筷子 if (left.tryLock()) { try { // 尝试获得右手筷子 if (right.tryLock()) { try { eat(); } finally { right.unlock(); } } } finally { left.unlock(); } } } } private void eat() { log.debug("eating..."); Sleeper.sleep(1); }}
4.4 公平锁
ReentrantLock默认是不公平的。(谁抢到就是谁的,所以是不公平的)synchronized也是不公平的。
4.5 条件变量
synchronized 中也有条件变量,就是我们讲原理时那个 waitSet 休息室,当条件不满足时进入 waitSet 等
ReentrantLock 的条件变量比 synchronized 强大之处在于,它是支持多个条件变量的,这就好比
- synchronized 是那些不满足条件的线程都在一间休息室等消息
- 而 ReentrantLock 支持多间休息室,有专门等烟的休息室、专门等早餐的休息室、唤醒时也是按休息室来唤醒
要点:
- await 前需要获得锁
- await 执行后,会释放锁,进入 conditionObject 等待
- await 的线程被唤醒(或打断、或超时)取重新竞争 lock 锁
- 竞争 lock 锁成功后,从 await 后继续执行
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月01日 16时19分25秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
微信js-sdk使用简述(分享,扫码功能等)
2019-03-05
c++中ifstream及ofstream超详细说明
2019-03-05
web项目配置
2019-03-05
基于单片机简易信号误差分析设计-全套资料
2019-03-05
基于单片机简易脉搏测量仪系统设计-毕设课设资料
2019-03-05
Javascript中String支持使用正则表达式的四种方法
2019-03-05
Servlet2.5的增删改查功能分析与实现------删除功能(四)
2019-03-05
spring启动错误:Could not resolve placeholder
2019-03-05
invalid byte sequence for encoding
2019-03-05
技术美术面试问题整理
2019-03-05
ORB-SLAM2:LoopClosing线程学习随笔【李哈哈:看看总有收获篇】
2019-03-05
js求阶乘
2019-03-05
Nginx---惊群
2019-03-05
项目中常用的审计类型概述
2019-03-05
(九)实现页面底部购物车的样式
2019-03-05
python-day3 for语句完整使用
2019-03-05
基于LabVIEW的入门指南
2019-03-05
weblogic之cve-2015-4852
2019-03-05