Java并发编程之ReadWriteLock读写锁的操作方法

作者:Java硬件工程师 时间:2023-12-07 20:08:37 

1.ReadWriteLock介绍

Java并发编程之ReadWriteLock读写锁的操作方法

为什么我们有了Lock,还要用ReadWriteLock呢。我们对共享资源加锁之后,所有的线程都将会等待。Lock读操作也锁,写操作也会锁,而对共享资源读的时候,其实是不用加锁的。当然读写同时存在的情况也会有。
比如我们数据库常用操作有增删改查,增删改都是写操作,写操作必须加锁,而读操作可以共享。不是所有的操作都需要加锁。
为了进一步提高复用性和粒度,写操作独占,读操作共享,不加锁。
ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
即读读可共享,写读写写要独占
读操作不用关心资源争抢和数据一致性的操作

多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源应该可以同时进行。
但是如果有一个线程想去写共享资源来,就不应该再有其它线程可以对该资源进行读或写。
小总结:
  读-读能共存
  读-写不能共存
  写-写不能共存

ReadWriteLock适用于读多写少的并 * 况。
Java并发包中ReadWriteLock是一个接口,主要有两个方法,如下:


public interface ReadWriteLock {
/**
 * 返回读锁
 */
Lock readLock();

/**
 * 返回写锁
 */
Lock writeLock();
}

Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。

2.不用读写锁的案例


class MyCache{
//volalite保证数据再线程间的可见性和一定的有序性
private volatile Map<String,Object> map=new HashMap<>();
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName()+"\t ---写入数据"+key);
map.put(key,value);
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"\t ---写入完成");
}
public void get(String key){
System.out.println(Thread.currentThread().getName()+"\t 读取数据");
Object result=map.get(key);
System.out.println(Thread.currentThread().getName()+"\t 读取完成"+result);
}

}
public class ReadWriteLockDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
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并发编程之ReadWriteLock读写锁的操作方法

上面的运行结果出现了一个很严重的问题,比如说,线程1在写入数据的时候,还没等线程1写完,其它线程也在写和读。这违背了事务的原子性。而且也破坏了数据的完整性和一致性,我正在写的时候,不允许其他线程同时也在写或者读。即1写入的时候,必须要满足后一条就是1写入完成。

3.用读写锁的案例


class MyCache{
//volalite保证数据再线程间的可见性和一定的有序性
private volatile Map<String,Object> map=new HashMap<>();
private ReadWriteLock readwritelock=new ReentrantReadWriteLock();
public void put(String key,Object value){
readwritelock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"\t ---写入数据"+key);
map.put(key,value);
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"\t ---写入完成");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
readwritelock.writeLock().unlock();
}
}
public void get(String key){
readwritelock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"\t 读取数据");
Object result=map.get(key);
System.out.println(Thread.currentThread().getName()+"\t 读取完成"+result);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
readwritelock.readLock().unlock();
}

}

}
public class ReadWriteLockDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
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并发编程之ReadWriteLock读写锁的操作方法

来源:https://blog.csdn.net/qq_39736597/article/details/113331843

标签:java,并发编程,ReadWriteLock,读写锁
0
投稿

猜你喜欢

  • 总结Bean的三种自定义初始化和销毁方法

    2023-01-05 13:38:09
  • java通过ip获取客户端Mac地址的小例子

    2021-12-22 06:37:07
  • java使用Socket类接收和发送数据

    2021-05-26 15:28:47
  • java启动线程的3种方式对比分析

    2023-12-17 08:38:41
  • Java面试必备之ArrayList陷阱解析

    2023-02-16 18:14:26
  • Android自定义View实现水波纹引导动画

    2021-07-02 05:42:25
  • java获取当前时间的四种方法代码实例

    2023-11-28 19:22:53
  • 浅析12306售票算法(java版)

    2023-11-16 10:27:12
  • Android实现记住账号密码功能

    2021-10-02 01:51:24
  • 浅析Android加载字体包及封装的方法

    2022-01-08 22:32:26
  • Mybatis-Plus分页的使用与注意事项

    2022-08-14 22:00:56
  • java生成图片验证码示例程序

    2023-09-13 10:17:57
  • Java基础教程之数组的定义与使用

    2022-04-24 10:24:12
  • 浅谈Java锁机制

    2022-01-09 00:58:56
  • C# Winform调用百度接口实现人脸识别教程(附源码)

    2021-12-27 13:17:09
  • Android自定义View软键盘实现搜索

    2022-02-10 07:22:45
  • WinForm中Application.Idle方法详解

    2022-09-05 01:53:06
  • C# Chart折线图使用鼠标滚轮放大、缩小和平移曲线方式

    2022-09-01 07:07:39
  • C#/VB.NET 自定义PPT动画路径的步骤

    2022-11-25 10:07:49
  • vc提示unexpected end of file found的原因分析

    2022-01-19 12:58:00
  • asp之家 软件编程 m.aspxhome.com