ReentrantReadWriteLock示例

public class ReentrantReadWriteLockTest {

    private Map<String, String> map = new HashMap<>();

    public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    //获取读锁
    private Lock readLock = readWriteLock.readLock();

    //获取写锁
    private Lock writeLock = readWriteLock.writeLock();

    public static void main(String[] args) throws InterruptedException {
        //testReenter();
        //testUpgrade();
        //testDowngrade();

        ReentrantReadWriteLockTest reentrantReadWriteLockTest = new ReentrantReadWriteLockTest();
          //写操作测试  可以知道写操作是互斥的
        Runnable runnable1 = () -> {
            for (int i = 0; i < 5; i++) {
                reentrantReadWriteLockTest.write("key" + i, "value"+i);
            }

        };
       Thread t1 =  new Thread(runnable1);
       Thread t2 =  new Thread(runnable1);
       Thread t3 =  new Thread(runnable1);
       t1.start();
       t2.start();
       t3.start();
       t1.join();
       t2.join();
       t3.join();
       System.out.println("开始并发读取。。。");

        //读操作测试  可以知道读操作是可以并发执行的
        Runnable runnable2 = () -> {
            for (int i = 0; i < 5; i++) {
                System.out.println(reentrantReadWriteLockTest.read("key" + i));
            }

        };
        new Thread(runnable2).start();
        new Thread(runnable2).start();
        new Thread(runnable2).start();
    }

   /**
           *  在同一个线程中,在没有释放写锁的情况下,就去申请读锁,这属于锁降级,ReentrantReadWriteLock是支持的,不过锁的释放有问题,获取到锁就要释放锁
          *  为什么有锁的降级,在一个线程进行写操作后,  当前线程可以继续读取数据,又不希望别的线程对数据更改,又可以让别的线程可以读取数据
   */
    public static void testDowngrade() {
        ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock();
        rtLock.writeLock().lock();
        System.out.println("writeLock");
        rtLock.readLock().lock();
        System.out.println("get read lock");
    }

    //在同一个线程中,在没有释放读锁的情况下,就去申请写锁,这属于锁升级,ReentrantReadWriteLock是不支持的。
    public static void testUpgrade() {
          ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock();
          rtLock.readLock().lock();
          System.out.println("get readLock.");
         // rtLock.readLock().unlock();
          rtLock.writeLock().lock();
          System.out.println("blocking");
          rtLock.writeLock().unlock();
    }

    //可重入锁,就是说一个线程在获取某个锁后,还可以继续获取该锁,即允许一个线程多次获取同一个锁,要注意的是获取多少次锁就要释放多少次锁,不然会发生死锁,例子讲的是两次获取写锁
    public static void  testReenter() throws InterruptedException {
        final ReentrantReadWriteLock  lock = new ReentrantReadWriteLock ();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.writeLock().lock();
                System.out.println("Thread real execute");
                lock.writeLock().unlock();
            }
        });

        lock.writeLock().lock();
        lock.writeLock().lock();
        t.start();
        Thread.sleep(200);
        System.out.println("realse one once");
        lock.writeLock().unlock();
      // lock.writeLock().unlock();
    }

    /**
              * 写操作
     * @param key
     * @param value
     */
    public void write(String key, String value) {
        writeLock.lock();
        System.out.println(Thread.currentThread().getName() + " 写操作正在执行。。。");
        try {
            Thread.sleep(2000);
            map.put(key, value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
    }

    /**
               * 读操作
     * @param key
     * @return
     */
    public String read(String key) {
        readLock.lock();
        System.out.println(Thread.currentThread().getName() + " 读操作正在执行。。。");
        try {
            Thread.sleep(2000);
            return map.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
        }
        return null;
    }
}

原文地址:https://www.cnblogs.com/moris5013/p/11764153.html

时间: 2024-10-17 08:30:16

ReentrantReadWriteLock示例的相关文章

Java锁--共享锁和ReentrantReadWriteLock

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3505809.html ReadWriteLock 和 ReentrantReadWriteLock介绍 ReadWriteLock,顾名思义,是读写锁.它维护了一对相关的锁 - - "读取锁"和"写入锁",一个用于读取操作,另一个用于写入操作."读取锁"用于只读操作,它是"共享锁",能同时被多个线程获取."写入锁"

Java线程同步和并发第1部分

通过优锐课核心java学习笔记中,我们可以看到,码了很多专业的相关知识, 分享给大家参考学习.我们将分两部分介绍Java中的线程同步,以更好地理解Java的内存模型. 介绍 Java线程同步和并发是复杂应用程序各个设计阶段中讨论最多的主题. 线程,同步技术有很多方面,它们可以在应用程序中实现高并发性. 多年来,CPU(多核处理器,寄存器,高速缓存存储器和主内存(RAM))的发展已导致通常是开发人员往往忽略的某些领域-例如线程上下文,上下文切换,变量可见性,JVM内存 型号与CPU内存型号. 在本

ReentrantReadWriteLock最最最经典示例用法

下面的代码展示了如何利用重入来执行升级缓存后的锁降级(为简单起见,省略了异常处理): class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release re

Java显式锁学习总结之五:ReentrantReadWriteLock源码分析

概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和Semaphore,AQS还可以混合两种模式使用,读写锁ReentrantReadWriteLock就是如此. 设想以下情景:我们在系统中有一个多线程访问的缓存,多个线程都可以对缓存进行读或写操作,但是读操作远远多于写操作,要求写操作要线程安全,且写操作执行完成要求对当前的所有读操作马上可见. 分析

Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(ReentrantLock)以及读写锁(ReentrantReadWriteLock). 1. ReentrantLock 在Java多线程(二) 多线程的锁机制 里面,已经总结过通过使用Synchronized关键字实现线程内的方法锁定.但使用Synchronized关键字有一些局限性,上锁和释放锁是由JVM决定的

【Java并发编程实战】—–“J.U.C”:ReentrantReadWriteLock

ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/读"."读/写"."写/写"操作都不能同时发生.然而在实际的场景中我们就会遇到这种情况:有些资源并发的访问中,它大部分时间都是执行读操作,写操作比较少,但是读操作并不影响数据的一致性,如果在进行读操作时采用独占的锁机制,这样势必会大大降低吞吐量.所以如果能够做

Java 1.7 ReentrantReadWriteLock源码解析

由于本人水平与表达能力有限,有错误的地方欢迎交流与指正. 1 简介 可重入读写锁时基于AQS实现的,典型的使用方法如JDK1.7中的示例: class RWDictionary { private final Map<String, Data> m = new TreeMap<String, Data>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final

【Java多线程】ReentrantReadWriteLock

概述 ReentrantReadWriteLock是Lock的另一种实现方式,ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程.写线程和写线程同时访问.相对于排他锁,提高了并发性.在实际应用中,大部分情况下对共享数据(如缓存)的访问都是读操作远多于写操作,这时ReentrantReadWriteLock能够提供比排他锁更好的并发性和吞吐量. 所谓读写锁,是对访问资源共享锁和排斥锁,一般

读写锁ReentrantReadWriteLock源代码浅析

1.简介 并发中常用的ReentrantLock,是一种典型的排他锁,这类锁在同一时刻只允许一个线程进行访问,实际上将并行操作变成了串行操作.在并发量大的业务中,其整体效率.吞吐量不能满足实现的需要.而且实际的业务中一般情况是读多于写,多个线程读操作不会改变已经有的数据,不会有数据的一致性问题,而一个写操作就会改变数据,其他的的读操作就可能读到过期的数据.读写锁正是为了这种业务需求而产生的,读写锁在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞.读写锁维护了