ReadWriteLock读写之间互斥吗?(详解)

发布于:2022-11-05 ⋅ 阅读:(252) ⋅ 点赞:(0)

开发中遇到并发的问题一般会用到锁,Synchronized存在明显的一个性能问题就是读与读之间互斥;

ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,以提升系统的性能。

ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁

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

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

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

public class ReadWriteLockTest {
    ReentrantReadWriteLock lock=new ReentrantReadWriteLock();
    ReentrantReadWriteLock.ReadLock readLock=lock.readLock(); //读锁
    ReentrantReadWriteLock.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 (Exception e){
            e.printStackTrace();
        }finally {
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockTest test=new ReadWriteLockTest();

        Thread t1=new Thread(new Runnable() { //读
            @Override
            public void run() {
                test.read();
            }
        },"t1");

        Thread t2=new Thread(new Runnable() { //读
            @Override
            public void run() {
                test.read();
            }
        },"t2");

        Thread t3=new Thread(new Runnable() { //写
            @Override
            public void run() {
                test.write();
            }
        },"t3");

        Thread t4=new Thread(new Runnable() { //写
            @Override
            public void run() {
                test.write();
            }
        },"t4");

        //t1.start();
        //t2.start();
        t3.start();
        t4.start();
    }

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

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

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

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

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

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

以上就是全部内容,希望对大家有帮助。


网站公告

今日签到

点亮在社区的每一天
去签到