美文网首页
读写锁的原理

读写锁的原理

作者: 猿必过 | 来源:发表于2021-03-13 10:15 被阅读0次

读写锁的使用

读写锁在 Java 中是 ReentrantReadWriteLock,使用方式是:

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo implements TestDemo {
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
    ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();

    private int x = 0;

    private void count() {
        writeLock.lock();
        try {
            x++;
        } finally {
            writeLock.unlock();// 保证当读的时候如果出现异常,会释放锁,synchronized为什么不用呢?因为synchronized内部已经帮我们做了~
        }
    }

    private void print(int time) {
        readLock.lock();
        try {
            for (int i = 0; i < time; i++) {
                System.out.print(x + " ");
            }
            System.out.println();
        } finally {
            readLock.unlock();// 保证当读的时候如果出现异常,会释放锁,synchronized为什么不用呢?因为synchronized内部已经帮我们做了~
        }
    }

    @Override
    public void runTest() {
    }
}

ReentrantReadWriteLock和ReentrantLock的区别?

使用ReentrantReadWriteLock读写锁的方式,会调用readLock()和writeLock()两个方法,看下他们的源码:

public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }

复制代码可以看到用到了WriteLock和ReadLock两个静态内部类,他们对锁的实现如下:

public static class ReadLock implements Lock, java.io.Serializable {
    public void lock() {
        sync.acquireShared(1); //共享
    }

    public void unlock() {
        sync.releaseShared(1); //共享
    }
}

public static class WriteLock implements Lock, java.io.Serializable {
    public void lock() {
        sync.acquire(1); //独占
    }

    public void unlock() {
        sync.release(1); //独占
    }
}

abstract static class Sync extends AbstractQueuedSynchronizer {}

看到这里发现了ReentrantReadWriteLock和ReentrantLock的一个相同点和不同点,
相同的是使用了同一个关键实现AbstractQueuedSynchronizer,不同的是ReentrantReadWriteLock使用了两个锁分别实现了AQS,
而且WriteLock和ReentrantLock一样,使用了独占锁。

而ReadLock和Semaphore一样,使用了共享锁。

再往下的内容估计看过前面几篇文章的都很熟悉了,独占锁通过state变量的0和1两个状态来控制是否有线程占有锁,共享锁通过state变量0或者非0来控制多个线程访问。

在上面的代码中,ReadLock和WriteLock使用了同一个AQS,那么在ReentrantReadWriteLock中又是怎么控制读锁和写锁关系的呢?

这当中还有一个问题,由于16位最大全1表示为65535,所以读锁和写锁最多可以获取65535个。

ReentrantReadWriteLock会发生写饥饿的情况吗?如果发生,有没有比较好的解决办法?

ReentrantReadWriteLock也会发生写请求饥饿的情况,因为写请求一样会排队,
不管是公平锁还是非公平锁,在有读锁的情况下,都不能保证写锁一定能获取到,这样只要读锁一直占用,就会发生写饥饿的情况。
那么JDK就没有提供什么好办法来解决这个问题吗?
当然是有的,那就是JDK8中新增的改进读写锁---StampedLock.

本文由猿必过 YBG 发布
禁止未经授权转载,违者依法追究相关法律责任
如需授权可联系:zhuyunhui@yuanbiguo.com

相关文章

  • 读写锁的原理

    读写锁的使用 读写锁在 Java 中是 ReentrantReadWriteLock,使用方式是: Reentra...

  • AbstractQueuedSynchronizer

    理解多线程的并发锁,可结合多进程的分布式锁(如Zookeeper的互斥锁、读写锁的实现原理),本质是相通的 介绍 ...

  • 线程同步(下)

    继上篇。这篇介绍的几种使用的较少。 读写锁 读写锁与互斥锁类似。不过读写锁允许更高的并行性。读写锁可以有三种状态:...

  • 读写锁和互斥锁 读写互斥锁,简称读写锁 mux sync.RWMutex Lock和Unlock分别对写锁进行锁定...

  • Java读写锁实现原理

    最近做的一个小项目中有这样的需求:整个项目有一份config.json保存着项目的一些配置,是存储在本地文件的一个...

  • 读写锁(ReentrantReadWriteLock)实现原理

    参考:http://ifeve.com/juc-reentrantreadwritelock/[http://if...

  • Java 读写锁实现原理

    最近做的一个小项目中有这样的需求:整个项目有一份config.json保存着项目的一些配置,是存储在本地文件的一个...

  • iOS 原理探究-读写锁

    读写锁是计算机程序的并发控制的一种同步机制,也称“共享-互斥锁”、多读者-单写者锁。读操作可并发重入,写操作是互斥...

  • Java并发编程-读写锁(ReentrantReadWriteL

    章节目录 ReentrantReadWriteLock 特性 读写锁接口示例 读写锁的实现分析读写状态设计写锁的释...

  • ReadWriteLock读写锁

    1、引入ReadWriteLock读写锁 ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有...

网友评论

      本文标题:读写锁的原理

      本文链接:https://www.haomeiwen.com/subject/trqxcltx.html