JAVA 并发编程-读写锁之模拟缓存系统(十一)
发布日期:2022-01-11 03:09:56
浏览次数:6
分类:技术文章
本文共 2560 字,大约阅读时间需要 8 分钟。
在多线程中,为了提高效率有些共享资源允许同时进行多个读的操作,但只允许一个写的操作,比如一个文件,只要其内容不变可以让多个线程同时读,不必做排他的锁定,排他的锁定只有在写的时候需要,以保证别的线程不会看到数据不完整的文件。这时候就需要使用读写锁。
- /**
- * 简单读写锁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线程间并不是互斥的。其实加读写锁的目的是同一把锁的读锁既可以与写锁互斥,读锁之间还可以共享。
转载地址:https://yuki-ho.blog.csdn.net/article/details/52316442 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2024年03月29日 20时53分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
squid 优化指南
2021-06-30
编程方式刷新Squid缓存服务器的五种方法
2021-06-30
centos vnc配置笔记
2021-06-30
Linux服务器网络开发模型
2021-06-30
nginx虚拟目录设置 alias 和 root
2021-06-30
理解http响应头中的Date和Age
2021-06-30
四层和七层负载均衡的区别
2021-06-30
设置Squid Cache_mem大小
2021-06-30
squid日志文件太大,怎样处理?
2021-06-30
让Squid 显示本地时间
2021-06-30
linux mysql 命令 大全
2021-06-30
清除Squid缓存的小工具
2021-06-30
Varnish Cache 3.0.0安装
2021-06-30
深入探讨Varnish缓存命中率
2021-06-30
Linux下文件如果没有权限不能被Apache访问
2021-06-30
Linux内核学习四库全书
2021-06-30
Linux内核模块编程入门
2021-06-30
使用Cacti监控你的网络Cacti的安装
2021-06-30
2011年6月编程语言关注度排行
2021-06-30