JAVA 并发编程-读写锁之模拟缓存系统(十一)
在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保证别的线程不会看到数据不完整的文件。这时候就须要使用读写锁。
/**
* 简单读写锁demo
* @author hejingyuan
*
*/
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();
//读数据
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 readdata!
Thread-2 be ready to readdata!
Thread-2have read data:null
Thread-0have read data:null
Thread-1 be ready towrite data!
Thread-1 have write data:1021
Thread-1 be ready towrite data!
Thread-1 have write data:2887
看到这里不免有人会问。既然读的时候能够多人訪问。那么为什么还要加读锁呢?
答:当然要加锁了,否则在写时去读,可能不对-(写的时候不能去读)
读写锁-模拟缓存系统实现:
public class CacheDemo {
private Map<String, Object> cache = new HashMap<String, Object>();
public static void main(String[] args) {
}
//定义读写锁
private ReadWriteLock rwl = new ReentrantReadWriteLock();
//读数据。使用读锁
public Object getData(String key){
//加入读锁
rwl.readLock().lock();
Object value = null;
try{
value = cache.get(key);
if(value == null){
//释放读锁
rwl.readLock().unlock();
//加上写锁
rwl.writeLock().lock();
try{
//如果三个线程同一时候去获取写锁,我们知道仅仅有第一个线程能够获取
//那么其它两个线程仅仅有等了,如果第一个线程按流程运行完后,刚才的两个线程能够得到写锁了,
//然后接着就能够改动数据了(赋值).所以加上推断!
if(value==null){//为什么还要推断?
value = "aaaa";//实际是去queryDB();
}
}finally{
//释放写锁
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
}finally{
rwl.readLock().unlock();
}
return value;
}
}
总结:
读写锁的作用为,当我们加上写锁时,其它线程被堵塞,仅仅有一个写操作在运行,当我们加上读锁后,它是不会限制多个读线程去訪问的。也就是get和put之间是相互排斥的。put与不论什么线程均为相互排斥。可是get与get线程间并非相互排斥的。事实上加读写锁的目的是同一把锁的读锁既能够与写锁相互排斥,读锁之间还能够共享。
JAVA 并发编程-读写锁之模拟缓存系统(十一)的更多相关文章
- java并发编程-读写锁
最近项目中需要用到读写锁 读写锁适用于读操作多,写操作少的场景,假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以 ...
- java并发:读写锁ReadWriteLock
在没有写操作的时候,两个线程同时读一个资源没有任何问题,允许多个线程同时读取共享资源. 但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写. 简单来说,多个线程同时操作同一资 ...
- 多线程之使用读写锁ReentrantReadWriteLock实现缓存系统
简单地缓存系统:当有线程来取数据时.假设该数据存在我的内存中.我就返回数据.假设不存在我的缓存系统中,那么就去查数据库.返回数据的同一时候保存在我的缓存中. 当中涉及到读写问题:当多个线程运行读操作时 ...
- Python并发编程-Memcached (分布式内存对象缓存系统)
一.Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的 ...
- Java并发编程实战3-可见性与volatile关键字
1. 缓存一致性问题 在计算机中,每条指令都是在CPU执行的,而CPU又不具备存储数据的功能,因此数据都是存储在主存(即内存)和外存(硬盘)中.但是,主存中数据的存取速度高于外存中数据的存取速度(这也 ...
- java并发编程-StampedLock高性能读写锁
目录 一.读写锁 二.悲观读锁 三.乐观读 欢迎关注我的博客,更多精品知识合集 一.读写锁 在我的<java并发编程>上一篇文章中为大家介绍了<ReentrantLock读写锁> ...
- 读《Java并发编程的艺术》(一)
离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督 ...
- 基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程
许多以Java多线程开发为主题的技术书籍,都会把对Java虚拟机和Java内存模型的讲解,作为讲授Java并发编程开发的主要内容,有的还深入到计算机系统的内存.CPU.缓存等予以说明.实际上,在实际的 ...
- 【Java并发编程】从CPU缓存模型到JMM来理解volatile关键字
目录 并发编程三大特性 原子性 可见性 有序性 CPU缓存模型是什么 高速缓存为何出现? 缓存一致性问题 如何解决缓存不一致 JMM内存模型是什么 JMM的规定 Java对三大特性的保证 原子性 可见 ...
随机推荐
- hibernate5.3版本出现hibernate中The server time zone value“乱码”问题的解决办法。
<!-- 配置关于数据库连接的四个项 driverClass url username password --> <property name="hibernate.con ...
- ios打电话发短信接口
电话.短信是手机的基础功能,iOS中提供了接口,让我们调用.这篇文章简单的介绍一下iOS的打电话.发短信在程序中怎么调用. 1.打电话 [[UIApplication sharedApplicatio ...
- $.fn.extend的用法
$.fn.extend({ sfMessages: function(m) { $("p.tips").html('<span class="circle ioc ...
- css float属性详解
定义和用法 float 属性定义元素在哪个方向浮动.以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动.浮动元素会生成一个块级框,而不论它本身是何种元素.如果浮动非 ...
- 关于C/C++的一些思考(3)
操作符重载函数(Operator Overload Function)的基本概念: 目的是以与对待内置数据类型相同的方式对待用户自定义类型(程序执行速度会受到影响),限制是不能随意选择函数名和参数个数 ...
- 笔试算法题(33):烙饼排序问题 & N!阶乘十进制末尾0的个数二进制最低1的位置
出题:不同大小烙饼的排序问题:对于N块大小不一的烙饼,上下累在一起,由于一只手托着所有的饼,所以仅有一只手可以翻转饼(假设手足够大可以翻转任意块数的 饼),规定所有的大饼都出现在小饼的下面则说明已经排 ...
- mysql主库与从库配置(并行复制配置)
主库: [mysqld] server-id = 2233port = 13306basedir = /usr/local/mysqldatadir = /usr/local/mysql/data s ...
- 树莓派 -- oled
硬件 SPI0,CE0 SPI Master Driver 设备树 arch\arm\boot\dts\bcm2710-rpi-3-b.dts &gpio { spi0_pins: spi0_ ...
- 集训第六周 数学概念与方法 概率 数论 最大公约数 G题
Description There is a hill with n holes around. The holes are signed from 0 to n-1. A rabbit must h ...
- jQuery学习之------元素样式的操作
jQuery学习之------元素样式的操作 一..addClass( className )方法----增加样式 1.addClass( className ) : 为每个匹配元素所要增加的一个或多 ...