【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 个月前
用volatile修饰数组代表什么意思,Java
java·juc·volatile
是三好2 个月前
并发容器(Collections)
java·多线程·juc
编程、小哥哥2 个月前
互联网大厂Java求职面试实录 —— 严肃面试官遇到搞笑水货程序员
java·面试·mybatis·dubbo·springboot·多线程·juc
yb0os12 个月前
手写一个简单的线程池
java·开发语言·数据库·计算机·线程池·juc
是三好2 个月前
Lock锁
java·juc
abc小陈先生2 个月前
JUC并发编程1
java·juc
左灯右行的爱情3 个月前
深入理解 G1 GC:已记忆集合(RSet)与收集集合(CSet)详解
java·jvm·后端·juc
左灯右行的爱情4 个月前
深入学习ReentrantLock
java·后端·juc
佛祖让我来巡山5 个月前
JUC相关知识点总结
juc
fly spider6 个月前
多线程-线程池的使用
java·面试·线程池·多线程·juc