【juc】读写锁ReentrantReadWriteLock

目录

一、说明

  • 1.当读操作远远高于写操作时,使用读写锁让读读可以并发,来提高性能
  • 2.类似于数据库中的select ... from ... lock in share mode
  • 3.提供一个数据容器类,内部分别使用读锁保护数据的read()方法,写锁保护数据的write()方法

二、读读不互斥

2.1 代码示例
复制代码
package com.learning;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
public class ReadWriteLockLearning {
    private Object data;
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();


    public Object read(){
        log.debug("获取读锁");
        readLock.lock();
        try {
            log.debug("读取");
            try {
                Thread.sleep(1000);
            }catch(Exception e){
                e.printStackTrace();
            }
            return data;
        }finally {
            log.debug("释放读锁");
            readLock.unlock();
        }
    }

    public void write(){
        log.debug("获取写锁");
        writeLock.lock();
        try{
            log.debug("写入");
        }finally {
            log.debug("释放写锁");
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockLearning readWriteLockLearning = new ReadWriteLockLearning();
        new Thread(()->{
            readWriteLockLearning.read();
        }, "t1").start();


        new Thread(()->{
            readWriteLockLearning.read();
        }, "t2").start();
    }
}
2.2 截图示例

三、读写互斥

3.1 代码示例
复制代码
package com.learning;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
public class ReadWriteLockLearning {
    private Object data;
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();


    public Object read(){
        log.debug("获取读锁");
        readLock.lock();
        try {
            log.debug("读取");
            return data;
        }finally {
            log.debug("释放读锁");
            readLock.unlock();
        }
    }

    public void write(){
        log.debug("获取写锁");
        writeLock.lock();
        try{
            log.debug("写入");
            try {
                Thread.sleep(1000);
            }catch(Exception e){
                e.printStackTrace();
            }
        }finally {
            log.debug("释放写锁");
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockLearning readWriteLockLearning = new ReadWriteLockLearning();
        new Thread(()->{
            readWriteLockLearning.read();
        }, "t1").start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            readWriteLockLearning.write();
        }, "t2").start();
    }
}
3.2 截图示例

四、写写互斥

4.1 代码示例
复制代码
package com.learning;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
public class ReadWriteLockLearning {
    private Object data;
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();


    public Object read(){
        log.debug("获取读锁");
        readLock.lock();
        try {
            log.debug("读取");
            return data;
        }finally {
            log.debug("释放读锁");
            readLock.unlock();
        }
    }

    public void write(){
        log.debug("获取写锁");
        writeLock.lock();
        try{
            log.debug("写入");
            try {
                Thread.sleep(1000);
            }catch(Exception e){
                e.printStackTrace();
            }
        }finally {
            log.debug("释放写锁");
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockLearning readWriteLockLearning = new ReadWriteLockLearning();
        new Thread(()->{
            readWriteLockLearning.write();
        }, "t1").start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            readWriteLockLearning.write();
        }, "t2").start();
    }
}
4.2 截图示例

五、注意事项

  • 1.读写不支持条件变量
  • 2.不支持重入时升级:持有读锁的情况下去获取写锁,会导致获取写锁永久等待
5.2.1 代码示例
复制代码
package com.learning;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
public class ReadWriteLockLearning2 {
    private Object data;
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();


    public void readWrite(){
        log.debug("获取读锁");
        readLock.lock();
        try {
            try{
                log.debug("获取写锁");
                writeLock.lock();
            }finally {
                log.debug("释放写锁");
                writeLock.unlock();
            }
        }finally {
            log.debug("释放读锁");
            readLock.unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockLearning2 readWriteLockLearning = new ReadWriteLockLearning2();
        readWriteLockLearning.readWrite();
    }
}
5.2.2 截图示例
  • 3.支持重入时降级:持有写锁的情况下去获取读锁
相关推荐
程序员二叉2 天前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc
程序员二叉2 天前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
程序员二叉3 天前
【JUC】AQS底层深度拆解|独占/共享模式|队列原理全详解
java·开发语言·面试·juc
fengxin_rou11 天前
Java并发手撕题详解:原理、实现与面试避坑指南
多线程·cas·juc·lru
fengxin_rou17 天前
【从零开始的JUC并发第四章】:JUC常用工具类
并发·juc
better_liang18 天前
每日Java面试场景题知识点之-JUC并发编程核心原理与实战
java·线程池·并发编程·juc·aqs·reentrantlock·concurrenthashmap
fengxin_rou18 天前
【juc第三章】:AQS机制全解
juc
fengxin_rou19 天前
【JUC第二章下】:锁机制&关键字
架构·事务·cas·juc·volatile
fengxin_rou20 天前
【JUC第二章上】:锁机制&关键字
开发语言·并发·juc·