java多线程-ReadWriteLock
大纲:
- ReadWriteLock接口
- ReentrantReadWriteLock
- ReentrantReadWriteLock使用
一、ReadWriteLock
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
- readLock获得读锁。
- writeLock获得写锁。
二、ReentrantReadWriteLock是ReadWriteLock的实现类
- ReentrantReadWriteLock内部维护了两个实现Lock接口的内部类ReadLock读锁,与WriteLock写锁。
- 仅写锁支持condition。
- 锁降级:写锁降级为读锁,获取写锁、获取读锁、释放写锁。
- 锁升级:不支持读锁升级为写锁。
- 线程间互斥关系:读读共享锁、读写独享锁、写写独享锁
public class Met {
ReadWriteLock lock = new ReentrantReadWriteLock();
public void read(Thread thread){
try {
lock.readLock().lock();
System.out.println(thread.getName()+"read lock");
for(int i =0;i<10;i++){
System.out.println(thread.getName()+":"+i);
}
} finally {
System.out.println(Thread.currentThread().getName()+"read unlock");
lock.readLock().unlock();
}
} public void write(Thread thread){
try {
lock.writeLock().lock();
System.out.println(thread.getName()+"write lock");
for(int i =0;i<10;i++){
System.out.println(thread.getName()+":"+i);
}
} finally {
System.out.println(Thread.currentThread().getName()+"write unlock");
lock.writeLock().unlock();
}
}
}public class ReadRunnable implements Runnable {
Met met;
ReadRunnable(Met met){
this.met = met;
}
@Override
public void run() {
met.read(Thread.currentThread());
}
}public class WriteRunnable implements Runnable {
Met met;
WriteRunnable(Met met){
this.met = met;
}
@Override
public void run() {
met.write(Thread.currentThread());
}
}class TestReadWrite {
public static void main(String[] args) {
Met met = new Met();
ReadRunnable read = new ReadRunnable(met);
WriteRunnable write = new WriteRunnable(met);
Thread threadread0 = new Thread(read);
Thread threadread1 = new Thread(read);
Thread threadwrite0 = new Thread(write);
threadread0.start();
threadread1.start();
threadwrite0.start();
}
}
三、ReentrantReadWriteLock使用
官方demo:更新缓存后的锁降级,保持读锁。
public class CachedData {
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
String data = "未更新"; //缓存数据
volatile boolean isValid; //缓存数据是否有效
void processCachedData(){
readWriteLock.readLock().lock();
System.out.println(Thread.currentThread().getName()+"readLock.lock");
//校验缓存数据是否有效,若无效跟新data,有效直接使用
if(!isValid){
System.out.println(Thread.currentThread().getName()+"readLock.unlock");
readWriteLock.readLock().unlock();
readWriteLock.writeLock().lock();
System.out.println(Thread.currentThread().getName()+"writeLock.lock");
//再次校验
if(!isValid){
data = "已更新";
isValid = true;
System.out.println(Thread.currentThread().getName()+">>>refresh data");
}
//写锁降级为读锁:释放写锁前获取读锁
readWriteLock.readLock().lock();
System.out.println(Thread.currentThread().getName()+"readLock.lock");
System.out.println(Thread.currentThread().getName()+"writeLock.unlock");
//写锁被释放,读锁依旧
readWriteLock.writeLock().unlock();
}
System.out.println(Thread.currentThread().getName()+">>>use data "+data);
System.out.println(Thread.currentThread().getName()+"readLock.unlock");
readWriteLock.readLock().unlock();
}
}
public class ReadWriteRunnable implements Runnable {
CachedData task;
public ReadWriteRunnable(CachedData task){
this.task = task;
}
@Override
public void run() {
task.processCachedData();
}
}
class TestReadWrite {
public static void main(String[] args) {
CachedData task = new CachedData();
ReadWriteRunnable readWriteRunnable = new ReadWriteRunnable(task);
new Thread(readWriteRunnable).start();
new Thread(readWriteRunnable).start();
new Thread(readWriteRunnable).start();
new Thread(readWriteRunnable).start();
new Thread(readWriteRunnable).start();
new Thread(readWriteRunnable).start();
}
}
java多线程-ReadWriteLock的更多相关文章
- Java 多线程 ReadWriteLock
ReadWriteLock是JDK 1.5提供的读写分离锁,可以减少锁竞争.例如,线程A1.A2和A3进行写操作,线程B1.B2和B3进行读操作,如果使用重入锁或者内部锁,那么理论上所有读之间.读与写 ...
- java多线程 -- ReadWriteLock 读写锁
写一条线程,读多条线程能够提升效率. 写写/读写 需要“互斥”;读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁 ...
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程系列--“JUC锁”01之 框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...
- java多线程系类:JUC锁:01之框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--"JUC锁"01之 框架02. Java多线程系列--"JUC锁&q ...
- java多线程编程
一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复 ...
- Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例
概要 前面对"独占锁"和"共享锁"有了个大致的了解:本章,我们对CountDownLatch进行学习.和ReadWriteLock.ReadLock一样,Cou ...
随机推荐
- CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
题意:给定 n * m 个数,然后每次只能把其中一个数减少d, 问你能不能最后所有的数相等. 析:很简单么,首先这个矩阵没什么用,用一维的存,然后找那个中位数即可,如果所有的数减去中位数,都能整除d, ...
- Android 控件在布局中按比例放置[转]
转自:http://netsky1990.blog.51cto.com/2220666/997452 在Android开发中常用到线性布局LinearLayout对界面进行具体的创建,其中 ...
- 编写高质量代码改善C#程序的157个建议——建议149:使用表驱动法避免过长的if和switch分支
建议149:使用表驱动法避免过长的if和switch分支 随着代码变得复杂,我们很容易被过长的if和switch分支困扰. 一个类枚举类型Week如下: enum Week { Monday, Tue ...
- unittest对单个测试类的多种测试执行方法总结
基于unittest测试框架编写的测试脚本,一般单个测试类下会有多个测试方法,unittest也提供多种测试执行方式,下面就不同方式或者需求一一实操并说明: 一.使用unittest下main()方法 ...
- Linux下MySQL表名不区分大小写的设置方法
MySQL表名不区分大小写的设置方法 在用centox安装mysql后,把项目的数据库移植了过去,发现一些表的数据查不到,排查了一下问题,最后发现是表名的大小写不一致造成的. mysql在window ...
- Delphi 实现 图灵机器人API(IDHTTP POST )
此功能所需的 Key及接口文档,都可以在图灵机器人的官网下载, 小伙伴们需要申请自己的图灵机器人账号. 申请方法请自行百度“图灵机器人” . 登录账号后,在左侧的[机器人接入],获取需要的信息,记得 ...
- js学习日记-对象字面量
一.对象字面量语法 var person={ name:'小王', age:18, _pri:233 } 成员名称的单引号不是必须的 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误 成员名相 ...
- ArcGIS应用——使用Python为图斑连续编号及扩展应用
为图斑连续编号 在GIS应用中,为图斑连续编号(编号递增)是一项常见的需求,利用ArcGIS,可以方便的实现. Python脚本如下: rec=0 def autoIncrement(): globa ...
- PostgreSQL按年月日分组
Select EXTRACT(year from cast(joindate as timestamp)) as Year, EXTRACT(month from cast(joindate as t ...
- centos7 守护进程
ASP.NET Core应用程序发布linux在shell中运行是正常的.可一但shell关闭网站也就关闭了,所以要配置守护进程, 用的是Supervisor,本文主要记录配置的过程和过程遇到的问题 ...