`

ReadWriteLock(三)

阅读更多
我们启动了5个读线程和2个写线程,运行结果如下:

Thread-0 waiting for read...
Thread-1 waiting for read...
Thread-2 waiting for read...
Thread-3 waiting for read...
Thread-4 waiting for read...
Thread-5 waiting for write...
Thread-6 waiting for write...
Thread-4 reads data: AAAAAAAAAA
Thread-3 reads data: AAAAAAAAAA
Thread-2 reads data: AAAAAAAAAA
Thread-1 reads data: AAAAAAAAAA
Thread-0 reads data: AAAAAAAAAA
Thread-5 wrote data: EEEEEEEEEE
Thread-6 wrote data: MMMMMMMMMM
Thread-1 waiting for read...
Thread-4 waiting for read...
Thread-1 reads data: MMMMMMMMMM
Thread-4 reads data: MMMMMMMMMM
Thread-2 waiting for read...
Thread-2 reads data: MMMMMMMMMM
Thread-0 waiting for read...
Thread-0 reads data: MMMMMMMMMM
Thread-4 waiting for read...
Thread-4 reads data: MMMMMMMMMM
Thread-2 waiting for read...
Thread-5 waiting for write...
Thread-2 reads data: MMMMMMMMMM
Thread-5 wrote data: GGGGGGGGGG
Thread-6 waiting for write...
Thread-6 wrote data: AAAAAAAAAA
Thread-3 waiting for read...
Thread-3 reads data: AAAAAAAAAA
......

可以看到,每次读/写都是完整的原子操作,因为我们每次写入的都是10个相同字符。并且,每次读出的都是最近一次写入的内容。

如果去掉ReadWriteLock:

package com.crackj2ee.thread;
public class DataHandler {

    // store data:
    private char[] buffer = "AAAAAAAAAA".toCharArray();

    public char[] read(String name) throws InterruptedException {
        char[] data = doRead();
        System.out.println(name + " reads data: " + new String(data));
        return data;
    }
    public void write(String name, char[] data) throws InterruptedException {
        System.out.println(name + " wrote data: " + new String(data));
        doWrite(data);
    }

    private char[] doRead() {
        char[] ret = new char[10];
        for(int i=0; i<10; i++) {
            ret[i] = buffer[i];
            sleep(3);
        }
        return ret;
    }
    private void doWrite(char[] data) {
        for(int i=0; i<10; i++) {
            buffer[i] = data[i];
            sleep(10);
        }
    }
    private void sleep(int ms) {
        try {
            Thread.sleep(ms);
        }
        catch(InterruptedException ie) {}
    }
}

运行结果如下:

Thread-5 wrote data: AAAAAAAAAA
Thread-6 wrote data: MMMMMMMMMM
Thread-0 reads data: AAAAAAAAAA
Thread-1 reads data: AAAAAAAAAA
Thread-2 reads data: AAAAAAAAAA
Thread-3 reads data: AAAAAAAAAA
Thread-4 reads data: AAAAAAAAAA
Thread-2 reads data: MAAAAAAAAA
Thread-3 reads data: MAAAAAAAAA
Thread-5 wrote data: CCCCCCCCCC
Thread-1 reads data: MAAAAAAAAA
Thread-0 reads data: MAAAAAAAAA
Thread-4 reads data: MAAAAAAAAA
Thread-6 wrote data: EEEEEEEEEE
Thread-3 reads data: EEEEECCCCC
Thread-4 reads data: EEEEEEEEEC
Thread-1 reads data: EEEEEEEEEE

可以看到在Thread-6写入EEEEEEEEEE的过程中,3个线程读取的内容是不同的。

分享到:
评论

相关推荐

    Java语言ReadWriteLock特性实例测试

    `main()`方法创建了三个线程,一个用于写操作,两个用于读操作。当写线程运行时,其他读线程会被阻塞,直到写线程完成写操作并释放写锁。 总的来说,ReadWriteLock提供了一种高效且灵活的方式来管理对共享资源的...

    Java多线程之readwritelock读写分离的实现代码

    PricesInfo 类有三个方法:getPrice1()、getPrice2()和setPrices()。getPrice1()和getPrice2()方法使用读锁来锁定资源,而setPrices()方法使用写锁来锁定资源。 在多线程环境下,我们可以使用多个线程来读取 ...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段27讲 ReadWriteLock&amp;ReentrantReadWriteLock详细讲解_.mp4  高并发编程第三阶段28讲 Condition初步使用,提出几个疑问_.mp4  高并发编程第三阶段29讲 关于Condition疑问的几个小实验,...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段27讲 ReadWriteLock&amp;ReentrantReadWriteLock详细讲解_.mp4  高并发编程第三阶段28讲 Condition初步使用,提出几个疑问_.mp4  高并发编程第三阶段29讲 关于Condition疑问的几个小实验,...

    JUC面试知识点手册快速版

    第三章:锁机制 3.1 ReentrantLock 3.2 ReadWriteLock 3.3 StampedLock 第四章:同步辅助工具 4.1 CountDownLatch 4.2 CyclicBarrier 4.3 Semaphore 4.4 Exchanger 第五章:原子类和无锁编程 5.1 ...

    多线程(22)读写锁分离模式1

    - `ReadWriteLockImpl`类:实现了`ReadWriteLock`接口,内部维护了三个计数器,分别记录正在写入的线程数、等待写入的线程数和正在读取的线程数。此外,还包含一个对象锁`MUTEX`,用于同步对这些计数器的访问。 - ...

    基于JDK源码解析Java领域中的并发锁之设计与实现.pdf

    三、Condition接口的设计与实现 Condition接口提供了比synchronized更细粒度的线程间通信机制,它允许线程等待特定条件,而不仅仅是等待锁的释放。当线程调用condition的await()方法时,会释放当前持有的锁,进入...

    8、读写锁ReentrantReadWriteLock&StampLock详解.pdf

    ### 三、StampLock详解 #### 3.1 StampLock简介 `StampLock`是Java 8引入的一种新的同步机制,它提供了比`ReentrantReadWriteLock`更细粒度的控制。与传统的读写锁不同,`StampLock`提供了一个版本号(或称作“戳记...

    JUC知识点总结(三)ReentrantLock与ReentrantReadWriteLock源码解析

    8. Lock接口 (ReentrantLock 可重入锁) 特性 ReentantLock 继承接口 Lock 并实现了接口中定义的方法, 它是一种可重入锁, 除了能完成 synchronized 所能完成的所有工作外,还提供了诸如可响应中断锁、可轮询锁...

    精心整理的AQS和JUC相关的面试题.pdf【ReentrantLock】

    ⼀、ReentrantLock重⼊锁 1.1&gt; 概述 1.2&gt; 中断响应 lockInterruptibly() ...三、Semaphore信号量 四、ReadWriteLock读写锁 五、CountDownLatch倒计时器 六、CyclicBarrier循环栅栏 七、LockSupport线程阻塞⼯具类

    面向Java锁机制的字节码自动重构框架.pdf

    为了验证Lock2Lock重构工具的有效性,使用了三个测试案例:红黑树、消费者生产者问题模型和SPECjbb2005。这些测试案例涵盖了不同的并发场景和数据结构,能够从不同的维度测试重构工具的性能。 7. 文档信息 文档中...

    java进阶提高学习教程-14锁机制.pptx

    Java 中的 ReentrantReadWriteLock 类是 ReadWriteLock 接口的实现类。 CAS CAS 是 Compare And Swap,即比较和交换。CAS 使用一个期望值与一个变量的当前值比较,如果当前变量的值与期望值相等,则用一个新值来...

    15个顶级Java多线程面试题答案

    例如,有T1、T2、T3三个线程,我们希望T2在T1执行完毕后再执行,T3则需在T2执行完毕后执行。可以通过`Thread.join()`方法来实现这一需求。 **方法介绍:** `join()`方法的功能是使异步执行的线程变为同步执行。即在...

    java多线程、锁的教程跟案例

    三、其他并发工具 - **Semaphore(信号量)**:控制同时访问特定资源的线程数量。 - **CountDownLatch**:一次性计数器,用于等待多个线程完成操作。 - **CyclicBarrier**:允许一组线程等待彼此到达某个屏障点后...

    java并发编程-AQS和JUC实战

    #### 三、Semaphore 信号量 - **概述**:`Semaphore` 是一种用于控制同时访问特定资源的线程数量的同步工具类。 - **常用方法**: - `acquire()`:获取许可,如果没有足够的许可,则等待。 - `release()`:释放一...

    wait,notify等线程知识.pdf

    #### 三、注意事项 1. **锁的获取与释放:** - 调用 `wait()`, `notify()`, `notifyAll()` 必须在 `synchronized` 块中,即必须先获得锁。 - 当线程调用 `wait()` 时,会释放锁;当线程被唤醒并重新获得锁后,会从...

    Java锁的种类以及区别

    #### 三、独享锁与共享锁 **1. 独享锁** 独享锁也称为排他锁,指的是在某个时间段内只允许一个线程获取锁,这意味着如果当前线程获得了锁,则其他线程必须等待直到该线程释放锁。 **2. 共享锁** 共享锁允许多个...

    美团系统交易面试资料整理.zip

    2. 锁机制:理解synchronized和Lock的区别,掌握ReentrantLock、ReadWriteLock的用法。 3. CountDownLatch、CyclicBarrier、Semaphore等并发工具类的应用场景及实现方式。 三、Java虚拟机(JVM) 1. 类加载机制:...

    Redisson 使用手册.pdf

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-...12. 第三方框架整合:Redisson可以与多种第三方框架进行整合,如Spring框架、Spring Cache、Hibernate、Java缓存标准规范JCache API(JSR-107)等。

Global site tag (gtag.js) - Google Analytics