Java多线程_ReentrantLock
ReentrantLock是重入锁,它与synchronized很像,它是synchronized的加强版,因为它具有一些synchronized没有的功能。
下面我们看看两者的区别:
synchronized具有一定的局限性:
- 当线程尝试获取锁的时候,如果获取不到锁会一直阻塞;
- 如果获取锁的线程进入休眠或者阻塞,除非当前线程异常,否则其他线程尝试获取锁必须一直等待;
- 是非公平的。
而ReentrantLock实现了AQS,可以完成下列功能:
- 可中断响应;
- 锁申请等待限时;
- 公平锁;
- 与Condition一起使用,实现synchronized与wait/notify的功能。
引入几个概念:
提到ReentrantLock,我们不得不明白几个概念:
- 可重入锁。可重入锁是指同一个线程可以多次获取同一把锁。ReentrantLock和synchronized都是可重入锁。
- 可中断锁。可中断锁是指线程尝试获取锁的过程中,是否可以响应中断。synchronized是不可中断锁,ReentrantLock则提供了中断功能。
- 公平锁与非公平锁。公平锁是指多个线程必须按顺序,不许插队。非公平锁允许插队。synchronized是非公平锁,而ReentrantLock的默认实现是非公平锁,但是也可以设置为公平锁。
- CAS,在前面已经提到。
使用示例
具体用法通过简单代码通过代码演示:
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo implements Runnable {
static ReentrantLock lock = new ReentrantLock();
static int count = 0;
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
ReentrantLockDemo r = new ReentrantLockDemo();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
//结果输出:20000
}
}
通过ReentrantLock解决死锁问题:
import java.util.concurrent.locks.ReentrantLock;
public class KillDeadlockDemo implements Runnable {
static ReentrantLock lock1 = new ReentrantLock();
static ReentrantLock lock2 = new ReentrantLock();
int lock;
public KillDeadlockDemo(int lock) {
super();
this.lock = lock;
}
@Override
public void run() {
try {
if (lock == 1) {
lock1.lockInterruptibly();
Thread.sleep(500);
lock2.lockInterruptibly();
} else {
lock2.lockInterruptibly();
Thread.sleep(500);
lock1.lockInterruptibly();
}
} catch (InterruptedException e) {
} finally {
if (lock1.isHeldByCurrentThread()) {
lock1.unlock();
}
if (lock2.isHeldByCurrentThread()) {
lock2.unlock();
}
System.out.println(Thread.currentThread().getName() + "退出!");
}
}
public static void main(String[] args) {
KillDeadlockDemo kdd1 = new KillDeadlockDemo(1);
KillDeadlockDemo kdd2 = new KillDeadlockDemo(2);
Thread t1 = new Thread(kdd1);
Thread t2 = new Thread(kdd2);
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt();
/*
*结果输出:
*Thread-1退出!
*Thread-0退出!
*/
}
}
使用 tryLock()或者tryLock(long timeout, TimeUtil unit) 方法进行一次限时的锁等待,也可以解决死锁问题:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; public class TryLockDemo implements Runnable {
static ReentrantLock lock = new ReentrantLock(); @Override
public void run() {
try {
if (lock.tryLock(1, TimeUnit.SECONDS)) {
Thread.sleep(1100);
} else {
System.out.println(Thread.currentThread().getName() + "获取锁失败!释放");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} public static void main(String[] args) {
TryLockDemo td = new TryLockDemo();
Thread thread1 = new Thread(td);
Thread thread2 = new Thread(td);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//结果输出:Thread-1获取锁失败!释放
}
}
公平锁演示:
import java.util.concurrent.locks.ReentrantLock;
public class FairLockDemo implements Runnable {
static ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
while (true) {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + " get lock");
Thread.sleep(1000);
} catch (InterruptedException e) {
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
FairLockDemo fld = new FairLockDemo();
Thread t1 = new Thread(fld);
Thread t2 = new Thread(fld);
Thread t3 = new Thread(fld);
t1.start();
t2.start();
t3.start();
/*
*Thread-0 get lock
*Thread-1 get lock
*Thread-2 get lock
*Thread-0 get lock
*Thread-1 get lock
*Thread-2 get lock
*..........
*/
}
}
浅谈原理
请转到:https://www.cnblogs.com/ericz2j/p/13445822.html
Java多线程_ReentrantLock的更多相关文章
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程基础知识篇
这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程--让主线程等待子线程执行完毕
使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...
- Java多线程 2 线程的生命周期和状态控制
一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...
- java 多线程 1 线程 进程
Java多线程(一).多线程的基本概念和使用 2012-09-10 16:06 5108人阅读 评论(0) 收藏 举报 分类: javaSE综合知识点(14) 版权声明:本文为博主原创文章,未经博 ...
- 一起阅读《Java多线程编程核心技术》
目录 第一章 Java多线程技能 (待续...)
- 第一章 Java多线程技能
1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...
随机推荐
- Day01_WebCrawler(网络爬虫)
学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"webcrawler"获取视频和教程资料! b站在线视 ...
- 机器学习笔记簿 降维篇 LDA 01
机器学习中包含了两种相对应的学习类型:无监督学习和监督学习.无监督学习指的是让机器只从数据出发,挖掘数据本身的特性,对数据进行处理,PCA就属于无监督学习,因为它只根据数据自身来构造投影矩阵.而监督学 ...
- 在Linux系统中使用Vim读写远程文件
大家好,我是良许. 今天我们讨论一个 Vim 使用技巧--用 Vim 读写远程文件.要实现这个目的,我们需要使用到一个叫 netrw.vim 的插件.从 Vim 7.x 开始,netrw.vim 就被 ...
- GitHub 热点速览 Vol.30:那些提升效率的小工具们
摘要:虽然 GitHub 是一个学习技术的好去处,但是除了学习,它还集提高"搬砖"效率于一身.GitHub 上散落着各式各样的小工具,比如本周特推的 Adobe 开源的 React ...
- PHP preg_filter() 函数
preg_filter 函数用于执行一个正则表达式搜索和替换.高佣联盟 www.cgewang.com 语法 mixed preg_filter ( mixed $pattern , mixed $r ...
- PHP is_infinite() 函数
------------恢复内容开始------------ 实例 判断一个值是否为无限值: <?php echo is_infinite(2) . "<br>" ...
- 6.18 省选模拟赛 树 倍增 LCT
LINK:树 考虑暴力 保存每个版本的父亲 然后暴力向上跳.得分20. 考虑离线 可以离线那么就可以先把树给搞出来 然后考虑求k级祖先 可以倍增求. 如何判断合法 其实要求路径上的边的时间戳<= ...
- LVS-DR实现mysql负载均衡集群
lvs-dr实现mysql负载均衡集群 环境说明: 服务器的操作系统均为centos7,vip和rip在同一网段,使用lvs-dr模型来实现mysql集群服务 所有服务器均已配置好处VIP外的静态IP ...
- SpringBoot一个依赖搞定session共享
原文:微信公众号:Java开发宝典 https://mp.weixin.qq.com/s/_VFY9lXqNhH8Nh4HC9tuMg 1. 前言 在传统的单服务架构中,一般来说,只有一个服务器,那 ...
- 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮
前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的 ...