• 阿里一面:ReadWriteLock 读写之间互斥吗?我竟然答不上来。。


    开发中遇到并发的问题一般会用到锁,Synchronized存在明显的一个性能问题就是读与读之间互斥;ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,以提升系统的性能。

    ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。
    Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。

    而读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥;读写锁维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。

    从源码中可以看出,读写锁中同样依赖队列同步器Sync(AQS)实现同步功能,而读写状态就是其同步器的同步状态。下面从例子中来说明:读读共享,读写互斥,写写互斥。

    代码如下:

    public class ReentrantWriteReadLockTest {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        ReadLock readLock = lock.readLock();
        WriteLock writeLock = lock.writeLock();
    
        public void read(){
            try {
                readLock.lock();
                System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");
                Thread.sleep(3000);
                System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                readLock.unlock();
            }
        }
    
        public void write(){
            try {
                writeLock.lock();
                System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");
                Thread.sleep(3000);
                System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                writeLock.unlock();
            }
        }
    
        public static void main(String[] args) {
            final ReentrantWriteReadLockTest wr = new ReentrantWriteReadLockTest();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    wr.read();
                }
            }, "t1");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    wr.read();
                }
            }, "t2");
            Thread t3 = new Thread(new Runnable() {
                public void run() {
                    wr.write();
                }
            }, "t3");
            Thread t4 = new Thread(new Runnable() {
                public void run() {
                    wr.write();
                }
            }, "t4");
    
            t1.start();
            t2.start();
            //t3.start();
            //t4.start();
        }
    }
    

    当我们启动线程t1和t2时,结果如下:

    线程t1和t2可以同时进入,说明了读读共享!

    当我们启动线程t2和t3时,结果如下:

    一个线程必须等待另一个线程退出,才能进入,说明了读写互斥!

    当我们启动线程t3和t4时,结果如下:

    一个线程必须等待另一个线程退出,才能进入,说明了写写互斥!

    来源:https://www.cnblogs.com/liuqing576598117/p/11168528.html

    近期热文推荐:

    1.1,000+ 道 Java面试题及答案整理(2022最新版)

    2.劲爆!Java 协程要来了。。。

    3.Spring Boot 2.x 教程,太全了!

    4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

    5.《Java开发手册(嵩山版)》最新发布,速速下载!

    觉得不错,别忘了随手点赞+转发哦!

  • 相关阅读:
    Java经典面试题及详解
    linux nc命令使用详解
    终端下更改文件显示颜色
    第二章 IoC Setter注入
    网络抓包wireshark
    一些软件软件开发原则
    开发原则之约定大于配置
    2016第31周六
    2016第31周五
    2016年第31周四
  • 原文地址:https://www.cnblogs.com/javastack/p/16008540.html
Copyright © 2020-2023  润新知