美文网首页
Java读写锁注意

Java读写锁注意

作者: TinyThing | 来源:发表于2019-07-30 19:20 被阅读0次

今天排查问题,发现读锁和写锁都被阻塞,而阻塞线程只持有读锁!

写demo模拟后出现了相同的问题:

        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        new Thread(() -> {
            lock.readLock().lock();
            sleep(120);
        }).start();


        new Thread(() -> {
            lock.writeLock().lock();
            sleep(120);
        }).start();

        lock.readLock().lock();
        System.out.println("finish");

打断点后,进入readLock().lock()方法,查看代码:

protected final int tryAcquireShared(int unused) {
            Thread current = Thread.currentThread();
            int c = getState();
            //如果当前有写锁,并且写锁不是本线程,则返回-1
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerThread() != current)
                return -1;
            int r = sharedCount(c);
            //关键在这里,判断读线程是否应该阻塞!
            if (!readerShouldBlock() &&
                r < MAX_COUNT &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                //......
            }
            return fullTryAcquireShared(current);
        }

继续跟进readerShouldBlock方法,可以看出端倪

final boolean readerShouldBlock() {
            /* As a heuristic to avoid indefinite writer starvation,
             * block if the thread that momentarily appears to be head
             * of queue, if one exists, is a waiting writer.  This is
             * only a probabilistic effect since a new reader will not
             * block if there is a waiting writer behind other enabled
             * readers that have not yet drained from the queue.
             */
            //大概翻译一下可知:
            //这个方法是为了避免写锁无限等待而采取的一种启发式方法;
            //当等待队列中的头部(如果存在的话)正好是获取写锁的线程,则阻塞;
            return apparentlyFirstQueuedIsExclusive();
}

由此可知,当有写锁在等待队列头部时,其他读锁都要阻塞!如果某个读线程阻塞了,而此时有写线程去获取锁,会被放入等待队列头部;之后如果再次有其他读线程,则全都会阻塞!这个设计感觉不是很合理...

相关文章

  • Java读写锁注意

    今天排查问题,发现读锁和写锁都被阻塞,而阻塞线程只持有读锁! 写demo模拟后出现了相同的问题: 打断点后,进入r...

  • ReentrantReadWriteLock源码解析

    ReentrantReadWriteLock编码示例 上面的代码展示读写锁的使用,读写锁的介绍参考Java锁[ht...

  • 锁2

    5、读写锁 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些。假设你的程序中涉及到...

  • 读写锁的原理

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

  • 读写锁

    读写锁在 Java 的实现是 ReentrantReadWriteLock,称为可重入读写锁。其与 Reentra...

  • Java 读写锁

    对于一个读写锁来说,同一时刻,可以有多个线程拿到读锁,只有一个线程拿到写锁。一旦一个线程拿到写锁,他们任何想要获取...

  • Java中对锁的理解

    Java中锁的种类划分 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁...

  • java并发之ReentrantReadWriteLock

    java并发之ReentrantReadWriteLock 知识导读 读写锁内部维护了两个分离的锁,读锁和写锁,两...

  • Java 读写锁 ReentrantReadWriteLock

    本文内容:读写锁 ReentrantReadWriteLock 的源码分析,基于 Java7/Java8。 阅读建...

  • Java锁的种类

    JAVA锁有哪些种类,以及区别(转) 公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向...

网友评论

      本文标题:Java读写锁注意

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