ReadWriteLock ReentrantReadWriteLock
ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。
读写锁比互斥锁允许对于共享数据更大程度的并发。每次只能有一个写线程,但是同时可以有多个线程并发地读数据。ReadWriteLock适用于读多写少的并发情况。
Java并发包中ReadWriteLock是一个接口,主要有两个方法,如下:
public interface ReadWriteLock {
/**
* 返回读锁
*/
Lock readLock();
/**
* 返回写锁
*/
Lock writeLock();
}
Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。
实例的代码
package cn.itcast.heima2; import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
for (int i = 0; i < 3; i++) { new Thread() {
public void run() {
while (true) {
q3.get();
}
} }.start(); new Thread() {
public void run() {
while (true) {
q3.put(new Random().nextInt(10000));
}
}
}.start();
} }
} class Queue3 {
private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
ReadWriteLock rwl = new ReentrantReadWriteLock(true); //true为公平锁,false则为打乱 public void get() {
rwl.readLock().lock(); //读锁上锁
try {
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + " have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.readLock().unlock(); //读锁解锁
}
} public void put(Object data) { rwl.writeLock().lock(); //写锁上锁
try {
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
Thread.sleep((long) (Math.random() * 1000));
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.writeLock().unlock(); //写锁解锁
} }
}
结果:
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-4 have read data :null
Thread-2 have read data :null
Thread-0 have read data :null
Thread-3 be ready to write data!
Thread-3 have write data: 8786
Thread-5 be ready to write data!
Thread-5 have write data: 4237
Thread-1 be ready to write data!
Thread-1 have write data: 2771
Thread-4 be ready to read data!
Thread-2 be ready to read data!
Thread-0 be ready to read data!
Thread-2 have read data :2771
Thread-0 have read data :2771
Thread-4 have read data :2771
Thread-3 be ready to write data!
Thread-3 have write data: 4449
Thread-5 be ready to write data!
ReadWriteLock ReentrantReadWriteLock的更多相关文章
- Java Concurrency - ReadWriteLock & ReentrantReadWriteLock
锁所提供的最重要的改进之一就是 ReadWriteLock 接口和它的实现类 ReentrantReadWriteLock.这个类提供两把锁,一把用于读操作和一把用于写操作.同一时间可以有多个线程执行 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- Java并发编程-总纲
Java 原生支持并发,基本的底层同步包括:synchronized,用来标示一个方法(普通,静态)或者一个块需要同步执行(某一时刻,只允许一个线程在执行代码块).volatile,用来标识一个变量是 ...
- Table of Contents - JavaSE
Java Bean Lombok IO Commons-IO - IOUtils Regular Expression 正则表达式常用操作 Concurrency java.util.concurre ...
- java总结
JUC概况 以下是Java JUC包的主体结构: ? Atomic : AtomicInteger ? Locks : Lock, Condition, ReadWriteLock ? Collect ...
- java核心-多线程-Java多线程编程涉及到包、类
Java有关多线程编程设计的类主要涉及两个包java.lang和java.util.concurrent两个包 java.lang包,主要是线程基础类 <1>Thread <2> ...
- 并发编程之 Java 三把锁
前言 今天我们继续学习并发.在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性.其中,synchronized 高频出现,因为他既保证了原 ...
- java并发初探ReentrantWriteReadLock
java并发初探ReentrantWriteReadLock ReenWriteReadLock类的优秀博客 ReentrantReadWriteLock读写锁详解 Java多线程系列--" ...
- JUC——检视阅读
JUC--检视阅读 参考资料 JUC知识图参考 JUC框架学习顺序参考 J.U.C学习总结参考,简洁直观 易百并发编程,实践操作1,不推荐阅读,不及格 JUC文章,带例子讲解,可以学习2 Doug L ...
随机推荐
- lintcode-->哈希函数
在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基 ...
- hibernate原生sql封装,报错信息:could not find setter for rownum_
今天用hibernate的时候,用了一个原生态sql做了一个分页查询,结果就报错了... 找到解决方法了:http://shmily2038.iteye.com/blog/1704963
- JavaI/O系统2
数据流: DataInputStream,DataOutputStream.可以用于与计算机无关的格式读写java的基本数据类型以及String对象 对象流: ObjectInputStream,Ob ...
- ARM的体系结构与编程系列博客——ARM的历史与应用范围
前言 最近我感觉自己比较浮躁,重来没有好好地沉下心来做一件事情,而且针对自己在专业水平上仍然还有很多欠缺,于是我想我应该为自己做些什么来证明一下自己真的是潜心研究东西的人,于是我萌生了一个想法,真正地 ...
- centos install 命令安装 mysql数据库
命令安装mysql就不需要自己去下载解压,超级方便 下载: wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm ...
- 使用JS导出页面内容到Excel
JS代码 <script> $(function(){ // 使用outerHTML属性获取整个table元素的HTML代码(包括<table>标签),然后包装成一个完整的HT ...
- android service服务的学习
1.Service简单概述 Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件.服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即 ...
- 如何解决“There is no locally stored library”的问题
今天我在用pyCharm开发网页的时候,用cdn引入js文件,但是程序报错,说“there is no locally stored library”.于是我上网找到了解决方案,特整理如下: 在你报错 ...
- python学习之老男孩python全栈第九期_数据库day004知识点总结 —— MySQL数据库day4
复习: 1. MySQL:文件管理的软件 2. 三部分: - 服务端 - SQL语句 - 客户端 3. 客户端: - MySQL - navicat 4. 授权操作: - 用户操作 - 授权操作 5. ...
- vue.js 项目打包
vuejs是个前端框架,npm run dev的目的在于前端开发的时候可以实时调试.所以npm run dev 只是开发时期会用到,在生产环境中我们应该使用nginx,apahce tomcat等应用 ...