java 读写锁的使用及它的优点

目录
  • 1.读写锁使用
    • 1.1 读读不互斥
    • 1.2 读写互斥
    • 1.3 写写互斥
  • 2.优点分析
  • 3.适用场景
  • 总结

前言:

读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的。总结来说,读写锁的特点是:读读不互斥、读写互斥、写写互斥

1.读写锁使用

在 Java 语言中,读写锁是使用 ReentrantReadWriteLock 类来实现的,其中:

  • ReentrantReadWriteLock.ReadLock表示读锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。
  • ReentrantReadWriteLock.WriteLock表示写锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。

它的基础使用如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 获得读锁
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 获得写锁
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 读锁使用
readLock.lock();
try {
    // 业务代码...
} finally {
    readLock.unlock();
}
// 写锁使用
writeLock.lock();
try {
    // 业务代码...
} finally {
    writeLock.unlock();
}

1.1 读读不互斥

多个线程可以同时获取到读锁,称之为读读不互斥,如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 创建读锁
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
Thread t1 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t1]得到读锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]释放读锁.");
        readLock.unlock();
    }
});
t1.start();
Thread t2 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t2]得到读锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]释放读锁.");
        readLock.unlock();
    }
});
t2.start();

以上程序执行结果如下: 

1.2 读写互斥

读锁和写锁同时使用是互斥的(也就是不能同时获得),这称之为读写互斥,如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 创建读锁
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 创建写锁
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 使用读锁
Thread t1 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t1]得到读锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]释放读锁.");
        readLock.unlock();
    }
});
t1.start();
// 使用写锁
Thread t2 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t2]得到写锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]释放写锁.");
        writeLock.unlock();
    }
});
t2.start();

以上程序执行结果如下: 

1.3 写写互斥

多个线程同时使用写锁也是互斥的,这称之为写写互斥,如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 创建写锁
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
Thread t1 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t1]得到写锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]释放写锁.");
        writeLock.unlock();
    }
});
t1.start();

Thread t2 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t2]得到写锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]释放写锁.");
        writeLock.unlock();
    }
});
t2.start();

以上程序执行结果如下: 

2.优点分析

  • 提高了程序执行性能:多个读锁可以同时执行,相比于普通锁在任何情况下都要排队执行来说,读写锁提高了程序的执行性能。
  • 避免读到临时数据:读锁和写锁是互斥排队执行的,这样可以保证了读取操作不会读到写了一半的临时数据。

3.适用场景

读写锁适合多读少写的业务场景,此时读写锁的优势最大。

总结

读写锁是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,而写锁则是互斥锁。它的完整规则是:读读不互斥、读写互斥、写写互斥。它适用于多读的业务场景,使用它可以有效的提高程序的执行性能,也能避免读取到操作了一半的临时数据。

到此这篇关于java 读写锁的使用及它的优点的文章就介绍到这了,更多相关Java读写锁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 重入锁和读写锁的具体使用

    重入锁 重入锁 ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.除此之外,该锁还支持获取锁时的公平和非公平性选择 所谓不支持重进入,可以考虑如下场景:当一个线程调用 lock() 方法获取锁之后,如果再次调用 lock() 方法,则该线程将会被自己阻塞,原因是在调用 tryAcquire(int acquires) 方法时会返回 false,从而导致线程阻塞 synchronize 关键字隐式的支持重进入,比如一个 synchronize 修

  • Java多线程编程中线程锁与读写锁的使用示例

    线程锁Lock Lock  相当于 当前对象的 Synchronized import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * Lock lock = new ReentrantLock(); * lock.lock(); lock.unLock(); * 类似于 synchronized,但不能与synchronized 混用 */ public class L

  • 举例说明Java多线程编程中读写锁的使用

    以下示例为 java api并发库中 ReentrantReadWriteLock自带的实例,下面进行解读 class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock();//@1 if (!cacheValid) { //

  • java 读写锁的使用及它的优点

    目录 1.读写锁使用 1.1 读读不互斥 1.2 读写互斥 1.3 写写互斥 2.优点分析 3.适用场景 总结 前言: 读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的.总结来说,读写锁的特点是:读读不互斥.读写互斥.写写互斥. 1.读写锁使用 在 Java 语言中,读写锁是使用 ReentrantReadWriteLock

  • Java 读写锁实现原理浅析

    最近做的一个小项目中有这样的需求:整个项目有一份config.json保存着项目的一些配置,是存储在本地文件的一个资源,并且应用中存在读写(读>>写)更新问题.既然读写并发操作,那么就涉及到操作互斥,这里自然想到了读写锁,本文对读写锁方面的知识做个梳理. 为什么需要读写锁? 与传统锁不同的是读写锁的规则是可以共享读,但只能一个写,总结起来为:读读不互斥,读写互斥,写写互斥,而一般的独占锁是:读读互斥,读写互斥,写写互斥,而场景中往往读远远大于写,读写锁就是为了这种优化而创建出来的一种机制. 注

  • Java 读写锁源码分析

    前言 在实际项目中,比如我们有一个共享资源文件,我们程序会会同时并发的去读.写这个共享资源文件,那怎么能保证在高并发场景下安全.高效读写呢?OK,看了下文便知 提示:以下是本篇文章正文内容,案例仅供参考 一.技术介绍 1.ReentranReadWriteLock是什么? ReadWriteLock提供了readLock和writeLock两种锁的操作机制,一个是读锁,一个是写锁,而它的实现类就是ReentranReadWriteLock 读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的

  • 一文了解Java读写锁ReentrantReadWriteLock的使用

    目录 概述 ReentrantReadWriteLock介绍 实战案例 验证读读共享模式 验证读写互斥模式 真实缓存例子 概述 ReentrantReadWriteLock不知道大家熟悉吗?其实在实际的项目中用的比较少,反正我所在的项目没有用到过. ReentrantReadWriteLock称为读写锁,它提供一个读锁,支持多个线程共享同一把锁.它也提供了一把写锁,是独占锁,和其他读锁或者写锁互斥,表明只有一个线程能持有锁资源.通过两把锁的协同工作,能够最大化的提高读写的性能,特别是读多写少的场

  • Java读写锁ReadWriteLock原理与应用场景详解

    Java并发编程提供了读写锁,主要用于读多写少的场景 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的. 所谓的读写锁(Readers-Writer Lock),顾名思义就是将一个锁拆分为读锁和写锁两个锁. 其中读锁允许多个线程同时获得,而写锁则是互斥锁,不允许多个线程同时获得写锁,

  • Java中读写锁ReadWriteLock的原理与应用详解

    目录 什么是读写锁? 为什么需要读写锁? 读写锁的特点 读写锁的使用场景 读写锁的主要成员和结构图 读写锁的实现原理 读写锁总结 Java并发编程提供了读写锁,主要用于读多写少的场景,今天我就重点来讲解读写锁的底层实现原理 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的. 所谓的读

  • Java并发编程之重入锁与读写锁

    重入锁 重入锁,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁阻塞,该特性的实现需要解决以下两个问题. 1.线程再次获取锁.锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取. 2.锁的最终释放.线程重复n次获取了锁,随后在第n次释放该锁后,其他线程能够获取到该锁.锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁被重复获取的次数,而锁被释放时,计数自减,当计数等于0时表示锁已经成功释放

  • java多线程-读写锁原理

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java Implementation) 读/写锁的重入(Read / Write Lock Reentrance) 读锁重入(Read Reentrance) 写锁重入(Write Reentrance) 读锁升级到写锁(Read to Write Reentrance) 写锁降级到读锁(Write to

  • Java多线程编程之读写锁ReadWriteLock用法实例

    读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可.如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁:如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁.总之,读的时候上读锁,写的时候上写锁! 三个线程读数据,三个线程写数据示例: 可以同时读,读的时候不能写,不能同时写,写的时候不能读. 读的时候上读锁,读完解锁:写的时候上写锁,写完解锁. 注意finally解锁. package com.ljq.test.th

随机推荐