显示锁ReentrantLock和Condition的使用
一、ReentrantLock
(1)、java.util.concurrent.locks包中的ReentrantLock就是重入锁,它实现了Lock接口,Lock加锁和解锁都是显示的。ReentrantLock重入锁可以实现synchronized关键字的功能。
主要方法:
lock:获得锁。
unlock:释放锁。
(2)、java对synchronized优化之后,ReentrantLock和synchronize大的区别:
a、锁的粒度,ReentrantLock更细,更灵活。
b、ReentrantLock可以指定锁的公平性。synchronize只能是非公平的。
c、ReentrantLock可以利用Condition(条件)类选择性分组唤醒线程。
d、ReentrantLock可以中断一个正在等待获取锁的线程。lockInterruptibly()。
(3)、典型的使用格式:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
测试i++的代码:
注意:必须在finally块中调用unlock语句释放锁,以确保即使在方法体中抛出异常(try块)锁也会释放锁。否则这个锁永远不释放。
/**
* @author monkjavaer
* @date 2018/12/16 22:24
*/
public class ReentrantLockService{ private Lock lock = new ReentrantLock();
private int count = 0; public void getCount(){
try {
//获得锁
lock.lock();
System.out.println("thread :"+Thread.currentThread().getName()+" count = "+count++);
} catch (Exception e) {
e.printStackTrace();
}finally {
//在finally块中调用unlock语句,以确保即使在方法体中抛出异常(try块)也会释放锁。
lock.unlock();
}
} public static void main(String[] args) {
ReentrantLockService service = new ReentrantLockService();
for(int i=0; i<100; i++){
new Thread("" + i){
@Override
public void run(){
service.getCount();
}
}.start();
}
} }
二、Condition
(1)、Condition通过Lock对象调用newCondition()方法获得。借助Lock,Condition可以实现wait && notify同样的功能。主要方法:
await(): 使当前线程等待
signal():唤醒一个等待的线程
signalAll():唤醒所有等待的线程
(2)、在使用Condition的方法时需要先获得锁,即调用Lock对象的lock()方法,否则会抛出IllegalMonitorStateException,因为没有监视器对象。
Condition使用实例:
/**
* @author monkjavaer
* @date 2018/12/18 21:14
*/
public class ConditionService {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition(); public void awaitTest(){
try {
lock.lock();
System.out.println("before await()");
condition.await();
System.out.println("after await()");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
} public void signalTest(){
try {
lock.lock();
System.out.println("before signal()");
condition.signal();
System.out.println("after signal()");
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
} public static void main(String[] args) {
ConditionService service = new ConditionService();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
service.awaitTest();
}
});
thread1.start(); Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
service.signalTest();
}
});
thread2.start();
}
}
显示锁ReentrantLock和Condition的使用的更多相关文章
- Java中的显示锁 ReentrantLock 和 ReentrantReadWriteLock
在Java1.5中引入了两种显示锁,分别是可重入锁ReentrantLock和可重入读写锁ReentrantReadWriteLock.它们分别实现接口Lock和ReadWriteLock.(注意:s ...
- 多线程并发编程之显示锁ReentrantLock和读写锁
在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是 ...
- 七 内置锁 wait notify notifyall; 显示锁 ReentrantLock
Object中对内置锁进行操作的一些方法: Java内置锁通过synchronized关键字使用,使用其修饰方法或者代码块,就能保证方法或者代码块以同步方式执行. 内置锁使用起来非常方便,不需要显式的 ...
- Java多线程之wait、notify/notifyAll 详解,用wait 和notifyAll 以及synchronized实现阻塞队列,多线程拓展之ReentrantLock与Condition
前言:这几天看了很多关于多线程的知识,分享一波.(但是目前接触的项目还未用到过,最多用过线程池,想看线程池 请看我之前的博客) 关于基本的理论等 参考如下: https://www.cnblogs.c ...
- 6.显示锁Lock 和 线程通信Condition
显示锁 Lock 一.用于解决多线程 安全问题的方式: synchronized: 1.同步代码块 2.同步方法 jdk1.5 后:第三种:同步锁Lock (注意:同步(synchro ...
- 使用ReentrantLock和Condition来代替内置锁和wait(),notify(),notifyAll()
使用ReentrantLock可以替代内置锁,当使用内置锁的时候,我们可以使用wait() nitify()和notifyAll()来控制线程之间的协作,那么,当我们使用ReentrantLock的时 ...
- Java 显示锁 之 重入锁 ReentrantLock(七)
ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁.另外,该锁还支持获取锁时的公平与非公平性的选择. 重入锁 ReentrantL ...
- Java并发——显示锁
Java提供一系列的显示锁类,均位于java.util.concurrent.locks包中. 锁的分类: 排他锁,共享锁 排他锁又被称为独占锁,即读写互斥.写写互斥.读读互斥. Java的ReadW ...
- Java多线程之ReentrantLock与Condition
一.ReentrantLock 1.ReentrantLock简介 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”.ReentrantLock 类实现了 Lock ,它拥有与 sy ...
随机推荐
- Android组件化开发(注意事项)
1.Manifest合并 在Android studio编译项目时,无论你使用了几个Module都会把所有Manifest最终合并成一个,需要我们注意的是application标签下这个几个属性引用的 ...
- HTML标签的分类
html中的标签元素大体被分为三种不同的类型:块状元素.内联元素和内联块状元素.常用的块状元素有:<div>.<p>.<h1>...<h6>.<o ...
- Apache与IIS端口冲突解决方法
在安装Apache或者php集成环境包是经常会遇到Apache的80端口被占用导致无法正常启动Apache. Win7可以通过如下方法解决(如果坚持要使用80端口的话): 1.打开"控制面板 ...
- 关于SQL Server数据表的五种约束
1.主键约束(PRIMARY KEY) 主键约束可以在表中定义一个主键值,它可以唯一确定表中每一条记录,每个表中只能有一个主键约束(只能有一个主键约束的意思并不是说受主键约束的列只能有一个),并且受主 ...
- OJB
OJB 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 对象关系桥(OJB)是一种对象关系映射工具,它能够完成从Java对象到关系数据库的透明存储. 英文名 OJB ...
- iview构建 初始化的时候不要装ESlint 太烦人了
iview构建 Node.js Vue(全局安装) npm install -g vue-cli npm install vue-cli 问题:发现如果不全局安装VUE-cli,\n在它初始化的时候, ...
- json 存 window.localStorage.setItem('hideColums',hideArr);
onColumnSwitch:function(row, $element){ //JSON.parse() var showColumns=$('#table').bootstrapTable('g ...
- Poi 写入图片进入excel
public static void cacheWritePicture(BufferedImage bufferImg, Sheet sheet, Workbook wb, int width, i ...
- 跳转QQ聊天窗口
1. 点击按钮跳转QQ聊天窗口,若不是好友,先加好友 <a href=" tencent://message/?uin=QQ号" target="_blank&qu ...
- Oracle排名函数(Rank)实例详解
这篇文章主要介绍了Oracle排名函数(Rank)实例详解,需要的朋友可以参考下 --已知:两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应 ...