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;
}
}
分享到:
相关推荐
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); // 使用springboot自动注入RedisTemplate @Autowired private RedisTemplate, Object> redisTemplate; // 其他实现方法 }...
3. **并发设计模式**:书中详细介绍了各种并发设计模式,如生产者消费者模型(BlockingQueue)、读写锁模式(ReadWriteLock)、双检查锁定模式(Double-Checked Locking)、线程池模式(ThreadPoolExecutor)等,...
第二章:基础同步工具 2.1 synchronized关键字 2.2 volatile关键字 第三章:锁机制 3.1 ReentrantLock 3.2 ReadWriteLock 3.3 StampedLock 第四章:同步辅助工具 4.1 CountDownLatch 4.2 CyclicBarrier ...
读写锁(`ReadWriteLock`)允许多个读者同时访问,但只允许一个写者;双端队列(`BlockingQueue`)常用于工作窃取或工作提交模式,可以有效地平衡负载。 另外,本书还涵盖了线程池的原理和使用,`ThreadPoolExecutor`的...
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID...
二、LockSupport工具类的设计与实现 LockSupport是线程阻塞和唤醒的低级工具,提供了park()和unpark()方法,用于线程的挂起和恢复。它是基于 Unsafe 类实现的,可以实现非阻塞的线程挂起,提高并发效率。 三、...
### 二、ReentrantReadWriteLock详解 #### 2.1 ReentrantReadWriteLock的实现 `ReentrantReadWriteLock`是Java并发库中提供的一个可重入的读写锁实现。它通过两个独立的锁——读锁和写锁来实现读写分离的目的。 - ...
在并发读写场景下,MyBatis使用Java并发库中的ReadWriteLock(具体实现为ReentrantReadWriteLock),通过锁机制确保在写入缓存时的线程安全性。 执行流程大致如下: 1. 在Service层调用Mapper接口的方法。 2. ...
高并发编程第三阶段27讲 ReadWriteLock&ReentrantReadWriteLock详细讲解_.mp4 高并发编程第三阶段28讲 Condition初步使用,提出几个疑问_.mp4 高并发编程第三阶段29讲 关于Condition疑问的几个小实验,...
高并发编程第三阶段27讲 ReadWriteLock&ReentrantReadWriteLock详细讲解_.mp4 高并发编程第三阶段28讲 Condition初步使用,提出几个疑问_.mp4 高并发编程第三阶段29讲 关于Condition疑问的几个小实验,...
二、Java锁机制 1. **内置锁(显式锁)** - ReentrantLock(可重入锁):提供与synchronized相似的功能,但更灵活,支持公平锁、非公平锁,以及可中断和定时尝试获取锁。 - ReadWriteLock(读写锁):...
#### 二、Condition 重入锁的搭配类 **2.1 概述** - `Condition` 是与 `ReentrantLock` 关联的条件变量接口,提供比 `Object` 的 `wait` 和 `notify` 方法更强大的功能。 - **常用方法**: - `void await()`:使...
#### 二、基本概念 在Java中,`wait()` 和 `notify()` 方法用于实现线程间的同步。它们属于 `Object` 类的方法,这意味着所有对象都可以作为同步锁来使用。 ##### 1. wait() `wait()` 方法用于使当前线程进入等待...
这种方法的核心在于使用一个Map来存储每个级别的RollingFileAppender实例,以及一个读写锁(`ReadWriteLock`)来保证线程安全。 ```java public class MultiFileAppender extends AppenderSkeleton { private ...
#### 二、可重入锁 可重入锁是指同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。也就是说,线程可以多次获取同一个锁而不会出现死锁的情况。这在某些情况下非常有用,因为它可以避免...
思维导图总结 一,非并发 幕布导图链接: ://mubu.com/doc95LpcV0Umt 二,并发 幕布导图链接: ://mubu.com/docfncDN6iU-t jdk源码阅读 一,非并发数据结构 二,并发数据结构 重入ReadWriteLock
思维导图总结 一,非并发 幕布导图链接: ://mubu.com/doc95LpcV0Umt 二,并发 幕布导图链接: ://mubu.com/docfncDN6iU-t jdk源码阅读 一,非并发数据结构 二,并发数据结构 重入ReadWriteLock 循环屏障
`ReadWriteLock.java`展示了读写锁的概念,读写锁允许多个线程同时读取数据,但在写入时,只能有一个线程访问,这样既保证了读操作的并发性,又避免了数据的不一致性。`ReentrantLock`是一个可重入锁,支持公平性和...
#### 二、Concurrent包提供的集合 ##### 1.1 ConcurrentHashMap `ConcurrentHashMap`是`HashMap`的一个线程安全版本,它支持并发读取和一定程度上的并发修改操作。相比于传统的`HashMap`或`Collections....
通过简单的 Java 8 lambda 表达式提供索引策略,可以按需添加二级索引以提供快速查找。 这受到的IndexedMap启发,但最适合单线程使用。 如果以后需要多线程使用,它也可以作为向 ScalaSTM 的迁移路径(ScalaSTM ...