Java Lock的使用
+ ReentrantLock类的使用
+ ReentrantReadWriteLock类的使用
1. 使用ReentrantLock类
ReentrantLock类能够实现线程之间同步互斥,并且在扩展功能上更加强大,例如
嗅探技术
、多路分支通知
等功能,在使用上比synchronized
更加灵活。
ReentrantLock类具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()
方法后面的任务。
ReentrantLock
实现了Lock
接口,该接口包含以下方法:
public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition();
}
关键字 synchronized 与 wait() 和 notify() / notifyAll() 方法结合可以实现等待/通知模型, ReentrantLock 类也可以实现同样的功能,需要借助 Condition对象。
Condition 对象是JDK1.5中出现的技术,它有更好的灵活性,比如可实现多路通知功能,也就是在一个 Lock 对象里面可以创建多个 Condition (即对象监视器)实例,线程对象可以注册在指定的 Condition 中,从而可以有选择性地进行线程通知,在调度线程上更加灵活。
使用 notify() / notifyAll() 方法进行通知时,被通知的线程由JVM随机选择。通过 ReentrantLock 结合 Condition 可以实现选择性通知。
synchronized 相当于整个 Lock 对象中只有一个单一的 Condition 对象,所有的线程都注册在它一个对象的身上。线程 notifyAll() 时,需要通知所有的 WAITING 线程,没有选择权。
Object 类中的 wait() 方法相当于 Condition 类中的 await() 方法。
Object 类中的 wait(long timeout) 方法相当于 Condition 类中的 await(long time,TimeUnit unit) 方法。
Object 类中的 notify() 方法相当于 Condition 类中的 signal() 方法。
Object 类中的 notifyAll() 方法相当于 Condition 类中的 signalAll() 方法。
公平锁与非公平锁
Lock 分为公平锁和非公平锁,公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的 FIFO先进先出顺序。非公平锁是一种获取锁的抢占机制,是随机获得锁的。
Lock方法
- 方法 int getHoldCount() 的作用是查询当前线程保持此锁定的个数,也就是调用 lock()方法的次数。
- 方法 int getQueueLength() 的作用是返回正在等待获取此锁定的线程估计数
- 方法 int getWaitQueueLength(Condition condition) 的作用是返回等待与此锁定相关的给定条件 Condition 的线程估计数。比如有5个线程,每个线程都执行了同一个 condition 对象的 await() 方法,则调用 getWaitQueueLength(condition) 方法返回的指为5.
- 方法 boolean hasQueuedThread(Thread thread) 的作用是查询指定的线程是否正在等待获取此锁定。
- 方法 boolean hasQueuedThreads() 的作用是差选是否有线程正在等待获取此锁定。
- 方法 boolean hasWaiters(Condition condition) 的作用是查询是否有线程正在等待与此锁定有关的 condition 条件。
- 方法 boolean isFair() 的作用是判断是不是公平锁。
- 方法 boolean isHeldByCurrentThread() 的作用是查询当前线程是否保持此锁定。
- 方法 boolean isLocked() 的作用是查询此锁定是否由任意线程保持。
- 方法 void lockInterruptibly() 的作用是:如果当前线程未被中断,则获取锁定;如果已经被中断则抛出异常( java.lang.InterruptedException ).
- 方法 boolean tryLock() 的作用是:仅在调用时锁未被另外线程保持的情况下,才获取此锁定。
- 方法 boolean tryLock(long timeout,TimeUnit unit) 的作用是:如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。
使用Condition对象可以对线程执行的业务进行排序规划
2. 使用ReentrantReadWriteLock类
读写锁有两个锁:一个是读操作相关的锁,也称为共享锁;一个是写操作相关的锁,也称为排他锁。
多个读锁之间不互斥;读锁与写锁互斥;写锁与写锁互斥。
package com.zxd.concurrent.learning; import java.util.concurrent.locks.ReentrantReadWriteLock; /**
* @author CoderZZ
* @Title: ${FILE_NAME}
* @Project: ConcurrentLearning
* @Package com.zxd.concurrent.learning
* @description: 读锁不互斥;读写、写写互斥
* @Version 1.0
* @create 2018-04-08 21:29
**/
public class ReentrantReadWriteLockTest { private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); public void read(){
try {
reentrantReadWriteLock.readLock().lock();
System.out.println("获得读锁"+Thread.currentThread().getName()+" timestamp:"+System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
reentrantReadWriteLock.readLock().unlock();
}
} public void write(){
try{
reentrantReadWriteLock.writeLock().lock();
System.out.println("获得写锁"+Thread.currentThread().getName()+" timestamp:"+System.currentTimeMillis());
Thread.sleep(10000);
}catch (Exception e){
e.printStackTrace();
}finally {
reentrantReadWriteLock.writeLock().unlock();
}
} public static void main(String[] args){
ReentrantReadWriteLockTest reentrantReadWriteLockTest = new ReentrantReadWriteLockTest();
Runnable readRunnable = new Runnable() {
@Override
public void run() {
reentrantReadWriteLockTest.read();
}
};
Thread threadA = new Thread(readRunnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(readRunnable);
threadB.setName("B");
threadB.start();
Runnable writeRunnable = new Runnable() {
@Override
public void run() {
reentrantReadWriteLockTest.write();
}
};
Thread writeA = new Thread(writeRunnable);
writeA.setName("writeA");
writeA.start();
Thread writeB = new Thread(writeRunnable);
writeB.setName("writeB");
writeB.start();
}
}
运行结果如下:
Java Lock的使用的更多相关文章
- 转载:Java Lock机制解读
Java Lock机制解读 欢迎转载: https://blog.csdn.net/chengyuqiang/article/details/79181229 1.synchronized synch ...
- Java Lock Example – ReentrantLock(java锁的例子)
Welcome to Java Lock example tutorial. Usually when working with multi-threaded environment, we use ...
- Java Lock ReentrantLock ReentrantReadWriteLock
Lock与Synchronized的区别: 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现: 2)synchronized在发生异 ...
- Java Lock
JVM中的另一种锁Lock的实现.与synchronized不同的是,Lock完全用Java写成,在java这个层面是无关JVM实现的.在java.util.concurrent.locks包中有很多 ...
- [Java] [Lock] [Synchronized VS ReentrantLock]
Overview java编写多线程程序时,为了保证线程安全,需要对数据进行同步,经常用到的两种同步方式就是synchronized和重入锁ReentrantLock. 相似点 都是加锁方式 都是阻塞 ...
- Java Lock & Condition
/* jdk1.5以后将同步和锁封装成了对象. 并将操作锁的隐式方式定义到了该对象中, 将隐式动作变成了显示动作. Lock接口: 出现替代了同步代码块或者同步函数.将同步的隐式锁操作变成现实锁操作. ...
- 深入分析 Java Lock 同步锁
前言 Java 的锁实现,有 Synchronized 和 Lock.上一篇文章深入分析了 Synchronized 的实现原理:由Java 15废弃偏向锁,谈谈Java Synchronized 的 ...
- java lock锁住特定对象
由于lock没有锁住特定对象的概念,该如何做到像synchronized同步块一样的效果呢? 答案:为每一个需要加锁的对像分配一把锁. 示例: List<User> users = new ...
- Java lock 能被中断, synchronized 不能被中断
1.lock是可中断锁,而synchronized 不是可中断锁 线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定, 如果使用 synchronized ,如果A不释放, ...
随机推荐
- HighCharts 动态设置 series
var series = new Array(); var map = response.extend.map; $.each(map, function (key,values) { series. ...
- k8s简单介绍
k8s是什么? 它是用来解决容器部署,调度,伸缩等基础的功能的软件 k8s的优点? 易学:轻量级,简单,容易理解 便携:支持公有云,私有云,混合云,以及多种云平台 可拓展:模块化,可插拔,支持钩子,可 ...
- mysql 查询锁表,解锁
//1.查看当前数据库锁表的情况 SELECT * FROM information_schema.INNODB_TRX; //2.杀掉查询结果中锁表的trx_mysql_thread_id ...
- Utf8 与 Utf8-BOM 的差异
1.先说差异,Utf8-BOM编码的字符串比Utf8编码的字符串,多了前缀\xEF\xBF\xBD,肉眼是看不出来的,解析出来的字符串的长度也正常 比如:"123456",Enco ...
- Linux crontab 每5秒钟执行一次 shell 脚本 的方法
Linux crontab 每5秒钟执行一次 shell 脚本 的方法 由于 Linux 的 crontab 的定时命令格式如下: minute hour day-of-month month-of- ...
- 2019.11.06 【每天学点SAP小知识】Day1 - ABAP 7.40新语法
最近看同事使用ABAP新语法贼溜,省了好多的功夫,还在使用老语法的我眼红了. 所以就自己补一补7.40之后语法,能够让自己写代码更顺畅吧. 今天学习内联申明 inline 意思是:当编译器发现某段代码 ...
- JavaScript高程第三版笔记-面向对象编程
之前有篇博客曾提到过一点js的面向对象编程:js面向对象编程. 这里就结合js高程详细剖析一下javascript的面向对象编程. 前序: 1⃣️Object.defineProperty() var ...
- phpstorm 远程连接服务器进行开发
phpstorm phpstorm是一款功能强大的ide编辑器,有了它,你敲代码速度能比用notepad++快数倍(初学者不建议使用ide,建议使用notepad++),缺点是没有固态的电脑带起来吃力 ...
- CentOS 安装jdk 1.8
方法一:手动解压JDK的压缩包,然后设置环境变量 1.在/usr/目录下创建java目录 [root@localhost ~]# mkdir/usr/java [root@localhost ~ ...
- Tensorflow实战第十一课(RNN Regression 回归例子 )
本节我们会使用RNN来进行回归训练(Regression),会继续使用自己创建的sin曲线预测一条cos曲线. 首先我们需要先确定RNN的各种参数: import tensorflow as tf i ...