`

ReadWriteLock(二)

阅读更多
readLock()用于获得读锁,readUnlock()释放读锁,writeLock()和writeUnlock()一样。由于锁用完必须释放,因此,必须保证lock和unlock匹配。我们修改DataHandler,加入ReadWriteLock:

package com.crackj2ee.thread;
public class DataHandler {
    // store data:
    private char[] buffer = "AAAAAAAAAA".toCharArray();
    // lock:
    private ReadWriteLock lock = new ReadWriteLock();

    public char[] read(String name) throws InterruptedException {
        System.out.println(name + " waiting for read...");
        lock.readLock();
        try {
            char[] data = doRead();
            System.out.println(name + " reads data: " + new String(data));
            return data;
        }
        finally {
            lock.readUnlock();
        }
    }

    public void write(String name, char[] data) throws InterruptedException {
        System.out.println(name + " waiting for write...");
        lock.writeLock();
        try {
            System.out.println(name + " wrote data: " + new String(data));
            doWrite(data);
        }
        finally {
            lock.writeUnlock();
        }
    }

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

public方法read()和write()完全封装了底层的ReadWriteLock,因此,多线程可以安全地调用这两个方法:

// ReadingThread不断读取数据:
package com.crackj2ee.thread;
public class ReadingThread extends Thread {
    private DataHandler handler;
    public ReadingThread(DataHandler handler) {
        this.handler = handler;
    }
    public void run() {
        for(;;) {
            try {
                char[] data = handler.read(getName());
                Thread.sleep((long)(Math.random()*1000+100));
            }
            catch(InterruptedException ie) {
                break;
            }
        }
    }
}

// WritingThread不断写入数据,每次写入的都是10个相同的字符:
package com.crackj2ee.thread;
public class WritingThread extends Thread {
    private DataHandler handler;
    public WritingThread(DataHandler handler) {
        this.handler = handler;
    }
    public void run() {
        char[] data = new char[10];
        for(;;) {
            try {
                fill(data);
                handler.write(getName(), data);
                Thread.sleep((long)(Math.random()*1000+100));
            }
            catch(InterruptedException ie) {
                break;
            }
        }
    }
    // 产生一个A-Z随机字符,填入char[10]:
    private void fill(char[] data) {
        char c = (char)(Math.random()*26+'A');
        for(int i=0; i<data.length; i++)
            data[i] = c;
    }
}

分享到:
评论

相关推荐

    Mybatis-plus基于redis实现二级缓存过程解析

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); // 使用springboot自动注入RedisTemplate @Autowired private RedisTemplate, Object&gt; redisTemplate; // 其他实现方法 }...

    Java并发编程:设计原则与模式(第二版)-3

    3. **并发设计模式**:书中详细介绍了各种并发设计模式,如生产者消费者模型(BlockingQueue)、读写锁模式(ReadWriteLock)、双检查锁定模式(Double-Checked Locking)、线程池模式(ThreadPoolExecutor)等,...

    JUC面试知识点手册快速版

    第二章:基础同步工具 2.1 synchronized关键字 2.2 volatile关键字 第三章:锁机制 3.1 ReentrantLock 3.2 ReadWriteLock 3.3 StampedLock 第四章:同步辅助工具 4.1 CountDownLatch 4.2 CyclicBarrier ...

    java并发编程(第二版)

    读写锁(`ReadWriteLock`)允许多个读者同时访问,但只允许一个写者;双端队列(`BlockingQueue`)常用于工作窃取或工作提交模式,可以有效地平衡负载。 另外,本书还涵盖了线程池的原理和使用,`ThreadPoolExecutor`的...

    mybatis+redis缓存配置

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID...

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

    二、LockSupport工具类的设计与实现 LockSupport是线程阻塞和唤醒的低级工具,提供了park()和unpark()方法,用于线程的挂起和恢复。它是基于 Unsafe 类实现的,可以实现非阻塞的线程挂起,提高并发效率。 三、...

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

    ### 二、ReentrantReadWriteLock详解 #### 2.1 ReentrantReadWriteLock的实现 `ReentrantReadWriteLock`是Java并发库中提供的一个可重入的读写锁实现。它通过两个独立的锁——读锁和写锁来实现读写分离的目的。 - ...

    MyBatis缓存机制深度解剖[收集].pdf

    在并发读写场景下,MyBatis使用Java并发库中的ReadWriteLock(具体实现为ReentrantReadWriteLock),通过锁机制确保在写入缓存时的线程安全性。 执行流程大致如下: 1. 在Service层调用Mapper接口的方法。 2. ...

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

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

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

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

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

    二、Java锁机制 1. **内置锁(显式锁)** - ReentrantLock(可重入锁):提供与synchronized相似的功能,但更灵活,支持公平锁、非公平锁,以及可中断和定时尝试获取锁。 - ReadWriteLock(读写锁):...

    java并发编程-AQS和JUC实战

    #### 二、Condition 重入锁的搭配类 **2.1 概述** - `Condition` 是与 `ReentrantLock` 关联的条件变量接口,提供比 `Object` 的 `wait` 和 `notify` 方法更强大的功能。 - **常用方法**: - `void await()`:使...

    wait,notify等线程知识.pdf

    #### 二、基本概念 在Java中,`wait()` 和 `notify()` 方法用于实现线程间的同步。它们属于 `Object` 类的方法,这意味着所有对象都可以作为同步锁来使用。 ##### 1. wait() `wait()` 方法用于使当前线程进入等待...

    log4j.properties配置分级别单独打印

    这种方法的核心在于使用一个Map来存储每个级别的RollingFileAppender实例,以及一个读写锁(`ReadWriteLock`)来保证线程安全。 ```java public class MultiFileAppender extends AppenderSkeleton { private ...

    Java锁的种类以及区别

    #### 二、可重入锁 可重入锁是指同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。也就是说,线程可以多次获取同一个锁而不会出现死锁的情况。这在某些情况下非常有用,因为它可以避免...

    jdk1.8-source-code-read:jdk1.8源码阅读

    思维导图总结 一,非并发 幕布导图链接: ://mubu.com/doc95LpcV0Umt 二,并发 幕布导图链接: ://mubu.com/docfncDN6iU-t jdk源码阅读 一,非并发数据结构 二,并发数据结构 重入ReadWriteLock

    jdk1.8-source-code:该项目为注解jdk源码,方便朋友阅读,提高世界编程水平!!

    思维导图总结 一,非并发 幕布导图链接: ://mubu.com/doc95LpcV0Umt 二,并发 幕布导图链接: ://mubu.com/docfncDN6iU-t jdk源码阅读 一,非并发数据结构 二,并发数据结构 重入ReadWriteLock 循环屏障

    线程整理1

    `ReadWriteLock.java`展示了读写锁的概念,读写锁允许多个线程同时读取数据,但在写入时,只能有一个线程访问,这样既保证了读操作的并发性,又避免了数据的不一致性。`ReentrantLock`是一个可重入锁,支持公平性和...

    Concurrent In java

    #### 二、Concurrent包提供的集合 ##### 1.1 ConcurrentHashMap `ConcurrentHashMap`是`HashMap`的一个线程安全版本,它支持并发读取和一定程度上的并发修改操作。相比于传统的`HashMap`或`Collections....

    indexedmap:索引地图

    通过简单的 Java 8 lambda 表达式提供索引策略,可以按需添加二级索引以提供快速查找。 这受到的IndexedMap启发,但最适合单线程使用。 如果以后需要多线程使用,它也可以作为向 ScalaSTM 的迁移路径(ScalaSTM ...

Global site tag (gtag.js) - Google Analytics