读写锁ReadWriteLock和缓存实例
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 Queue queue = new Queue();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
queue.get();
}
} }.start(); new Thread() {
public void run() {
while (true) {
queue.put( new Random().nextInt(10000));
}
} }.start();
} }
} class Queue {
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();
} }
}
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheDemo { private static Map<String, Object> cache = new HashMap<String, Object>(); 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 {
// 再次判断该值是否为空,因为如果两个写线程都阻塞在这里,
// 当一个线程被唤醒后value的值为null则进行数据加载,当另外一个线程也被唤醒如果不判断就会执行两次写
if (value == null) {
value = "" ; // query 数据库
cache.put(key, value);
}
} finally {
rwl.writeLock().unlock(); // 释放写锁
}
rwl.readLock().lock(); // 写完之后降级为读锁
}
} finally {
rwl.readLock().unlock(); // 释放读锁
} return value;
} }
读写锁ReadWriteLock和缓存实例的更多相关文章
- 线程中的读写锁ReadWriteLock
Lock锁还有两个非常强大的类 ReadWriteLock接口实现类ReentrantReadWriteLock(非常重要的锁) 想实现 读取的时候允许多线程并发访问,写入的时候不允许. 这种效果.. ...
- 显式锁(三)读写锁ReadWriteLock
前言: 上一篇文章,已经很详细地介绍了 显式锁Lock 以及 其常用的实现方式- - ReetrantLock(重入锁),本文将介绍另一种显式锁 - - 读写锁ReadWriteLock. ...
- 多线程编程_读写锁ReadWriteLock
Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读 ...
- JAVA 并发编程-读写锁之模拟缓存系统(十一)
在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保 ...
- 【漫画】互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock
ReentrantLock完美实现了互斥,完美解决了并发问题.但是却意外发现它对于读多写少的场景效率实在不行.此时ReentrantReadWriteLock来救场了!一种适用于读多写少场景的锁,可以 ...
- 【漫画】读写锁ReadWriteLock还是不够快?再试试StampedLock!
本文来源于公众号[胖滚猪学编程] 转载请注明出处! 在互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock一文中,我们对比了互斥锁ReentrantLock和读写锁ReadWr ...
- 读-写锁 ReadWriteLock & 线程八锁
读-写锁 ReadWriteLock: ①ReadWriteLock 维护了一对相关的锁,一个用于只读操作, 另一个用于写入操作. 只要没有 writer,读取锁可以由 多个 reader 线程同时保 ...
- Java 读写锁 ReadWriteLock 原理与应用场景详解
Java并发编程提供了读写锁,主要用于读多写少的场景,今天我就重点来讲解读写锁的底层实现原理@mikechen 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Loc ...
- C# 多线程编程之锁的使用【互斥锁(lock)和读写锁(ReadWriteLock)】
多线程编程之锁的使用[互斥锁(lock)和读写锁(ReadWriteLock)] http://blog.csdn.net/sqqyq/article/details/18651335 多线程程序写日 ...
随机推荐
- sys.argv[]基本用法
#python 3.4.2 #windows系统下可以在CMD下执行 python test.py 第一参数 第2个参数 #空格分隔每个参数,sys.argv[]是用来获取命令行参数的 #引用必要的包 ...
- JDK1.5新特性(六)……Generics
概述 Generics - This long-awaited enhancement to the type system allows a type or method to operate on ...
- eclipse配置tomcat加大内存的方法
双击tomcat -Dcatalina.base="E:\work\whykt\.metadata\.plugins\org.eclipse.wst.server.core\tmp0&quo ...
- Objective-C之消息机制
话说2014年4月编程语言排行榜中Objective-C的使用比又增加了,看来IOS和MAX OS的开发者是真给力呀. 不过个人感觉用不了多久,IOS和Android的开发者收入就不会有那么大的差异了 ...
- Android Socket 相关
http://www.imooc.com/learn/223 http://www.epubit.com.cn/book/onlinechapter/12093
- 【转载】C/C++语言void及void指针深层探索
C/C++语言void及void指针深层探索 1.概述许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误.本文将对void关键字的深刻含义进行解说,并详述vo ...
- 天天动听MP3解码器性能提升50%
天天动听今日升级提醒,发现有一句 “使用新的MP3解码器,性能提升50%”,太惊讶了. 之前版本的MP3解码器使用libmpg123,效果已经是MP3解码器中非常不错的了. 50%的提升,应该不仅仅是 ...
- TreeView节点
TreeView由节点构成,建树通过对TreeView.items属性进行操作.Items是一个TTreeNodes对象,这是一个TTreeNode集. 一.针对TTreeNodes,也就是 Tree ...
- [Objective-c 基础 - 2.7] 构造方法、重写init方法
A.id 万能指针,可以指向任何对象,实质是NSObject的指针,使用的时候不用加上* B.NSObject中得类方法new 1.完整地创建一个可用对象步骤 (1)分配存储空间 + alloc ...
- gulp 基础运用
全局安装gulp $npm install --global gulp 作为项目的开发依赖安装 //--save-dev 开发依赖,储存在package.json的devDependencies中,如 ...