ReadWriteLock 读写之间互斥吗?我竟然答不上来。。

简介: ReadWriteLock 读写之间互斥吗?我竟然答不上来。。

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


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


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

image.png

从源码中可以看出,读写锁中同样依赖队列同步器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时,结果如下:

image.png

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


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

image.png

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


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

image.png

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


相关文章
|
缓存 安全 Java
【JavaSE专栏78】线程同步,控制多个线程之间的访问顺序和共享资源的安全性
【JavaSE专栏78】线程同步,控制多个线程之间的访问顺序和共享资源的安全性
|
Python
互斥访问
Python 中的线程锁是为了在多线程环境下保证对共享资源的互斥访问而设计的。可以使用 Python 的threading模块中的Lock类来创建线程锁。 以下是使用线程锁的一个简单示例:
70 0
|
4月前
|
算法 Java 程序员
同步与互斥(二)
同步与互斥(二)
79 0
|
5月前
|
存储 安全 Linux
【Linux】线程安全——补充|互斥、锁|同步、条件变量(上)
【Linux】线程安全——补充|互斥、锁|同步、条件变量(上)
59 0
|
5月前
|
安全 算法 Linux
【Linux】线程安全——补充|互斥、锁|同步、条件变量(下)
【Linux】线程安全——补充|互斥、锁|同步、条件变量(下)
53 0
|
7月前
|
存储 缓存 安全
Java并发基础之互斥同步、非阻塞同步、指令重排与volatile
在Java中,多线程编程常常涉及到共享数据的访问,这时候就需要考虑线程安全问题。Java提供了多种机制来实现线程安全,其中包括互斥同步(Mutex Synchronization)、非阻塞同步(Non-blocking Synchronization)、以及volatile关键字等。 互斥同步(Mutex Synchronization) 互斥同步是一种基本的同步手段,它要求在任何时刻,只有一个线程可以执行某个方法或某个代码块,其他线程必须等待。Java中的synchronized关键字就是实现互斥同步的常用手段。当一个线程进入一个synchronized方法或代码块时,它需要先获得锁,如果
65 0
|
缓存 Oracle 关系型数据库
【数据设计与实现】第5章:同步与互斥
同步与互斥设计原则数据库的一个重要能力就是为多个用户提供并发访问服务,并发度是考察数据库性能的重要指标之一。事务隔离级别定义了并发控制算法的正确性,并让用户通过选择隔离级别在正确性和高性能之间进行平衡。事务重点考虑的是数据层面的并发控制,是属于较上层的同步与互斥。实际上,数据库系统是由大量进程、线程、数据结构构成的,进程、线程会并发地访问、修改数据结构,还需要在较底层级解决数据结构的同步与互斥问题
【数据设计与实现】第5章:同步与互斥
|
安全 Java 数据安全/隐私保护
|
Java 安全 测试技术
线程同步方法和差别~(高并发中多个线程访问统一资源域,容易出现线程安全性)
同步就是指一个线程要等待上一个线程执行完之后才开始执行当前的线程; 异步是指一个线程去执行,它的下一个线程不必等待它执行完就开始执行。 同步优势:java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突, 因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性(保证线程安
2507 0