一、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的使用的更多相关文章

  1. Java中的显示锁 ReentrantLock 和 ReentrantReadWriteLock

    在Java1.5中引入了两种显示锁,分别是可重入锁ReentrantLock和可重入读写锁ReentrantReadWriteLock.它们分别实现接口Lock和ReadWriteLock.(注意:s ...

  2. 多线程并发编程之显示锁ReentrantLock和读写锁

    在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是 ...

  3. 七 内置锁 wait notify notifyall; 显示锁 ReentrantLock

    Object中对内置锁进行操作的一些方法: Java内置锁通过synchronized关键字使用,使用其修饰方法或者代码块,就能保证方法或者代码块以同步方式执行. 内置锁使用起来非常方便,不需要显式的 ...

  4. Java多线程之wait、notify/notifyAll 详解,用wait 和notifyAll 以及synchronized实现阻塞队列,多线程拓展之ReentrantLock与Condition

    前言:这几天看了很多关于多线程的知识,分享一波.(但是目前接触的项目还未用到过,最多用过线程池,想看线程池 请看我之前的博客) 关于基本的理论等 参考如下: https://www.cnblogs.c ...

  5. 6.显示锁Lock 和 线程通信Condition

    显示锁 Lock 一.用于解决多线程 安全问题的方式: synchronized:   1.同步代码块      2.同步方法 jdk1.5 后:第三种:同步锁Lock  (注意:同步(synchro ...

  6. 使用ReentrantLock和Condition来代替内置锁和wait(),notify(),notifyAll()

    使用ReentrantLock可以替代内置锁,当使用内置锁的时候,我们可以使用wait() nitify()和notifyAll()来控制线程之间的协作,那么,当我们使用ReentrantLock的时 ...

  7. Java 显示锁 之 重入锁 ReentrantLock(七)

    ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁.另外,该锁还支持获取锁时的公平与非公平性的选择. 重入锁 ReentrantL ...

  8. Java并发——显示锁

    Java提供一系列的显示锁类,均位于java.util.concurrent.locks包中. 锁的分类: 排他锁,共享锁 排他锁又被称为独占锁,即读写互斥.写写互斥.读读互斥. Java的ReadW ...

  9. Java多线程之ReentrantLock与Condition

    一.ReentrantLock 1.ReentrantLock简介 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”.ReentrantLock 类实现了 Lock ,它拥有与 sy ...

随机推荐

  1. HTML5应用缓存与Web Workers

    1.什么是应用程序缓存      HTML5引入了应用程序缓存,这意味着web应用可进行缓存,并可在没有因特网链接时进行访问. 2.应用缓存的优势      离线浏览   用户可在应用离线时使用它们 ...

  2. 使用Glide加载Android图片

    一.概述 Glide是一个在Android端非常好的图片缓冲工具,总体上来说,他有以下优点 使用简单 自适应程度高 支持常见的图片格式,如jpg,png等 支持多种数据源,网络,本地,资源,Asset ...

  3. 掌握Spark机器学习库-06-基础统计部分

    说明 本章主要讲解基础统计部分,包括基本统计.假设检验.相关系数等 数据集 数据集有两个文件,分别是: beijing.txt 北京历年降水量,不带年份 beijing2.txt 北京历年降水量,带年 ...

  4. redis-cli 工具--raw参数的作用

    最近阅读了以redis官网关于--raw参数的解释,其功能有两个: 1.按数据原有格式打印数据,不展示额外的类型信息 例如:使用命令发送方式(redis在使用时有命令发送方式和交互方式两种)创建一个k ...

  5. 关于mapState和mapMutations和mapGetters 和mapActions辅助函数的用法及作用(三)-----mapGetters

    简单的理解: const getters = { newCount: function(state){ return state.count += 5; } } ------------------- ...

  6. spring 获取ApplicationContext

    第一种:获取根目录下的文件名 ApplicationContext ac = new ClassPathXmlApplicationContext("../mvc-dispatcher-se ...

  7. Log4net快速搭建

    nuget安装log4net 2018.12.10当前版本为2.0.8 找到所在项目的[Properties->AssemblyInfo] 在底部加上 [assembly: log4net.Co ...

  8. 洛谷 P3388 【模板】割点

    题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...

  9. ubuntu15.04安装 RVM

    首先,请参考这篇文章 https://ruby-china.org/wiki/rvm-guide RVM 官方网站 https://rvm.io/ 1 由于现在很多网站都转向https链接,所以,根据 ...

  10. 【经验分享】IMX6开发板编译问题及解决方法

    本文转自迅为IMX6开发板售后讨论群,分享给大家~物理主机 win10 64 位专业版.虚拟机 VM12 Pro.开发环境采用迅为提供的开发环境:Ubuntu12.04.2 .镜像采用最新的:iTOP ...