1) Reader&Writer Problem Intro
1> Reader&Writer task may share a resource, say a DB.
2> Many Reader may access a DB without fear of data corruption.
3> Only one Writer may access a DB at a time.
Read Access: If no threads are writing, and no threads have acquired the write access.
Write Access: If no threads are reading or writing.
2) Read&Write Lock
1> Read&Write Lock is especially useful for Reader&Writer Problem
when there are many threads that read from a data structure and fewer threads that modify it.
2> It makes sense to allow shared access for the readers. And a writer must still have exclusive access.
3) Example
package edu.xmu.thread; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; public class ReadeWriteLockTest { public static void main(String[] args) { Calculator calculator = new Calculator(2); Thread reader = new Thread(new Reader(calculator)); Thread reader2 = new Thread(new Reader(calculator)); Thread writer = new Thread(new Writer(calculator)); reader.start(); reader2.start(); writer.start(); } } class Reader implements Runnable { Calculator calculator; public Reader(Calculator calculator) { super(); this.calculator = calculator; } @Override public void run() { while (true) { int sum = calculator.getSum(); System.out.println("Thread: " + Thread.currentThread() + " finished getSum(), sum = " + sum); try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Writer implements Runnable { Calculator calculator; public Writer(Calculator calculator) { super(); this.calculator = calculator; } @Override public void run() { while (true) { calculator.add((int) (10 * Math.random())); try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Calculator { ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); ReadLock readLock; WriteLock writeLock; int sum; public Calculator(int sum) { super(); this.sum = sum; readLock = readWriteLock.readLock(); writeLock = readWriteLock.writeLock(); } public void add(int i) { writeLock.lock(); System.out.println("Thread: " + Thread.currentThread() + " get into add(" + i + ")"); try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } sum += i; System.out.println("Thread: " + Thread.currentThread() + " finished add(" + i + ")"); writeLock.unlock(); } public int getSum() { readLock.lock(); System.out.println("Thread: " + Thread.currentThread() + " get into getSum()"); readLock.unlock(); return sum; } }
Output:
Thread: Thread[Thread-0,5,main] get into getSum() // thread-0 got read lock Thread: Thread[Thread-1,5,main] get into getSum() // thread-1 got read lock Thread: Thread[Thread-0,5,main] finished getSum(), sum = 2 // thread-0 released read lock Thread: Thread[Thread-1,5,main] finished getSum(), sum = 2 // thread-1 released read lock Thread: Thread[Thread-2,5,main] get into add(4) // thread-2 got write lock and no other write/read lock may be got before this write lock released Thread: Thread[Thread-2,5,main] finished add(4) // thread-2 released write lock and other write/read lock may be got again. Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-1,5,main] finished getSum(), sum = 6 Thread: Thread[Thread-0,5,main] finished getSum(), sum = 6 Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-1,5,main] finished getSum(), sum = 6 Thread: Thread[Thread-2,5,main] get into add(5) Thread: Thread[Thread-2,5,main] finished add(5) Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-0,5,main] finished getSum(), sum = 11 Thread: Thread[Thread-1,5,main] finished getSum(), sum = 11 Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-0,5,main] finished getSum(), sum = 11 Thread: Thread[Thread-2,5,main] get into add(1) Thread: Thread[Thread-2,5,main] finished add(1) Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-1,5,main] finished getSum(), sum = 12 Thread: Thread[Thread-2,5,main] get into add(6) Thread: Thread[Thread-2,5,main] finished add(6) Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-0,5,main] finished getSum(), sum = 18
Reference Links:
1) http://www.cs.wustl.edu/~fredk/Courses/cs422/sp03/Lectures/concurrency2.pdf
2) http://tutorials.jenkov.com/java-concurrency/read-write-locks.html
3) http://java.dzone.com/news/java-concurrency-read-write-lo
相关推荐
`ReentrantReadWriteLock`包含两个内部类:`ReadLock`和`WriteLock`。`ReadLock`代表读锁,`WriteLock`代表写锁。读锁是共享的,可以被多个读取线程同时持有;而写锁是独占的,任何时候只能被一个写入线程持有。 ...
**读者-写者锁(Reader-Writer Lock)详解** 在多线程编程中,读者-写者锁(Reader-Writer Lock)是一种高级的同步机制,它允许多个读取操作并发进行,但当有写入操作时,会独占资源,以确保数据的一致性。在Java中...
在Java编程语言中,我们常常会遇到Reader/Writer Lock(读写锁)的概念,它是一种高级的同步机制,能够高效地支持多个读取者同时访问,但只允许一个写入者进行修改。 本文将详细解析"RICM4 - TP SE - 读写器"的相关...
在这个实验中,可能会使用两个信号量:一个用于表示当前是否有写者正在工作(writelock),另一个用于记录当前的读者数量(readcount)。 2. **PV操作**:P操作(Wait)用于申请资源,V操作(Signal)用于释放资源...
标题中的"Reader-Writer-Threading"直译为"读写器线程",指的是在多线程环境下,设计一个系统来支持多个读者同时读取共享数据,但仅允许一个写入者进行修改。这种问题的解决方案通常涉及线程之间的协调和互斥,以...
- **ReentrantReadWriteLock**:读写锁的实现,包含ReadLock和WriteLock,读锁可共享,写锁独占。 - **StampedLock**:Java 8引入的锁,支持读、写和乐观读三种模式,提供更细粒度的锁控制。 **并发工具类**: - **...
Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME); if (!writeLock.obtain(writeLockTimeout)) // 获取写锁文件 throw new LockObtainFailedException("Index locked for write: " + writeLock...
lock.readLock().lock(); try { // 访问资源 System.out.println("Reader reading: " + resource.getData()); } finally { lock.readLock().unlock(); } } // 写操作 public void write(int value) { ...
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock(); ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock(); ``` 使用读锁和写锁的方式如下: ```java ...
通过调用`readLock()`和`writeLock()`方法,可以分别获取读锁和写锁。 8. **异常处理**:在实现过程中,需要考虑死锁、活锁和饥饿等问题,确保代码能够正确地响应中断和超时。 9. **性能优化**:优化读者写者问题...
readLock.lock() block() readLock.unlock() } func writeBlock(block: () -> Void) { writeLock.lock() block() writeLock.unlock() } } ``` 4. **NSLock**:苹果提供的轻量级互斥锁,基于Objective-C,...
* Lock readLock() – 返回读锁 * Lock writeLock() – 返回写锁 其中,读锁可以同时被很多线程获得,只要不进行写操作。写锁同时只能被一个线程获取。 ReentrantLock ReentrantLock 是 Lock 的一个实现,什么是 ...
- 可能有`readLock().lock()`和`writeLock().lock()`来分别获取读锁和写锁。 在实际开发中,合理使用读写锁可以显著提高多线程环境下对共享资源的访问效率,减少不必要的等待时间。理解读写锁的工作原理及其在`...
lock.readLock().lock(); double value = price1; lock.readLock().unlock(); return value; } public double getPrice2() { lock.readLock().lock(); double value = price2; lock.readLock().unlock(); ...
读写锁通常包括两个锁:读锁(`ReadLock`)和写锁(`WriteLock`)。当多个线程进行读操作时,它们可以同时获得读锁;当有一个线程进行写操作时,其他所有线程(无论是读还是写)都必须等待。 **示例:** - `...
在公平模式下,`readLock().lock()`和`writeLock().lock()`会遵循FIFO(先进先出)原则,等待最久的线程将首先获得锁。当一个写者在写入时,所有读者和写者都会被阻塞;当写者完成写入并释放写锁后,如果有等待的...
- 使用`ReentrantReadWriteLock`并正确使用`readLock()`和`writeLock()`方法。 - 避免死锁和活锁的情况,确保线程间的锁获取顺序一致。 - 检查所有锁的释放,避免内存泄漏或线程阻塞。 - 检查共享数据结构是否为线程...
2. **ReadWriteLock**:Java的java.util.concurrent.locks.ReadWriteLock接口提供了读写锁,它分为读锁和写锁。读锁可以被多个线程同时获取,而写锁具有独占性,即只有一个线程可以获取。在读者写者问题中,我们可以...
在这个版本中,`readLock()`和`writeLock()`分别对应读者和写者的锁。读锁是共享的,允许多个线程同时持有;而写锁是独占的,一次只能有一个线程持有。这大大提高了系统的并发性能。 在`Test`类中,通常会创建多个...
ReadWriteLock提供了读锁(ReadLock)和写锁(WriteLock)。读锁可被多个线程共享,允许多个线程同时读取数据;写锁则是独占的,确保写操作的互斥。在某些读操作频繁的场景下,使用ReadWriteLock可以显著提高系统...