李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java锁--读写锁简介
Leefs
2020-02-23 AM
2038℃
0条
# Java锁--读写锁简介 **1.ReadWriteLock同Lock一样也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个是只读的锁,一个是写锁。** 读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的(排他的)。 每次只能有一个写线程,但是可以有多个线程并发地读数据。 所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。 理论上,读写锁比互斥锁允许对于共享数据更大程度的并发。与互斥锁相比,读写锁是否能够提高性能取决于读写数据的频率、读取和写入操作的持续时间、以及读线程和写线程之间的竞争。 **2.使用场景** 假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。 > 例如,最初填充有数据,然后很少修改的集合,同时频繁搜索(例如某种目录)是使用读写锁的理想候选项。 在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写。这就需要一个读/写锁来解决这个问题。 **3.互斥原则** > - 读-读:能共存, > - 读-写:不能共存, > - 写-写:不能共存。 **4.ReadWriteLock接口源码示例** ```java public interface ReadWriteLock { /** * Returns the lock used for reading. */ Lock readLock(); /** * Returns the lock used for writing. */ Lock writeLock(); } ``` **5.没加读写锁代码示例** ```java class MyCache{ private volatile Map
map = new HashMap<>(); public void put(String key,Object value){ System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key); try { TimeUnit.MILLISECONDS.sleep(300); }catch (InterruptedException e){ e.printStackTrace(); } map.put(key,value); System.out.println(Thread.currentThread().getName()+"\t 写入完成!"); } public void get(String key){ System.out.println(Thread.currentThread().getName()+"\t 正在读取!"); try { TimeUnit.MILLISECONDS.sleep(300); }catch (InterruptedException e){ e.printStackTrace(); } Object result = map.get(key); System.out.println(Thread.currentThread().getName()+"\t 读取完成:"+result); } } public class ReadWriteLockDemo { public static void main(String[] args) { MyCache myCache = new MyCache(); for(int i=1;i<=5;i++){ final int tempInt = i; new Thread(()->{ myCache.put(tempInt+" ",tempInt+" "); },String.valueOf(i)).start(); } for(int i=1;i<=5;i++){ final int tempInt = i; new Thread(()->{ myCache.get(tempInt+""); },String.valueOf(i)).start(); } } } ``` **运行结果** ```java 2 正在写入:2 1 正在写入:1 3 正在写入:3 4 正在写入:4 2 正在读取! 1 正在读取! 5 正在写入:5 3 正在读取! 4 正在读取! 5 正在读取! 4 读取完成:null 5 读取完成:null 3 读取完成:null 5 写入完成! 1 读取完成:null 2 读取完成:null 3 写入完成! 4 写入完成! 1 写入完成! 2 写入完成! ``` 在写入数据的情况下还可以进行数据的读取操作。 **加入读写锁代码示例** ```java class MyCache{ private volatile Map
map = new HashMap<>(); private ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock(); public void put(String key,Object value){ rwlock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key); try { TimeUnit.MILLISECONDS.sleep(300); }catch (InterruptedException e){ e.printStackTrace(); } map.put(key,value); System.out.println(Thread.currentThread().getName()+"\t 写入完成!"); }catch (Exception e){ e.printStackTrace(); }finally { rwlock.writeLock().unlock(); } } public void get(String key){ rwlock.readLock().lock(); try { System.out.println(Thread.currentThread().getName()+"\t 正在读取!"); try { TimeUnit.MILLISECONDS.sleep(300); }catch (InterruptedException e){ e.printStackTrace(); } Object result = map.get(key); System.out.println(Thread.currentThread().getName()+"\t 读取完成:"+result); }catch (Exception e){ e.printStackTrace(); }finally { rwlock.readLock().unlock(); } } } public class ReadWriteLockDemo { public static void main(String[] args) { MyCache myCache = new MyCache(); for(int i=1;i<=5;i++){ final int tempInt = i; new Thread(()->{ myCache.put(tempInt+" ",tempInt+" "); },String.valueOf(i)).start(); } for(int i=1;i<=5;i++){ final int tempInt = i; new Thread(()->{ myCache.get(tempInt+""); },String.valueOf(i)).start(); } } } ``` **运行结果** ```java 1 正在写入:1 1 写入完成! 2 正在写入:2 2 写入完成! 3 正在写入:3 3 写入完成! 4 正在写入:4 4 写入完成! 5 正在写入:5 5 写入完成! 1 正在读取! 2 正在读取! 3 正在读取! 4 正在读取! 5 正在读取! 2 读取完成:null 1 读取完成:null 4 读取完成:null 3 读取完成:null 5 读取完成:null ``` 在线程写入的时候不允许执行其他线程方法,在读取时候可以线程争抢资源。 *附:参考原文链接https://blog.csdn.net/j080624/article/details/82790372*
标签:
并发编程
,
锁
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/640.html
上一篇
集合类不安全之并发修改异常
下一篇
Java锁--自旋锁简介
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
队列
ClickHouse
VUE
RSA加解密
Eclipse
LeetCode刷题
Zookeeper
Linux
查找
DataWarehouse
前端
nginx
微服务
Azkaban
Spark Core
持有对象
设计模式
Hive
稀疏数组
JavaScript
数据结构
BurpSuite
Quartz
随笔
Ubuntu
Python
线程池
链表
国产数据库改造
Java工具类
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭