ReadWriteLock(一)

xiaoxiao2026-08-17  1

线程读写同一个对象的数据是很普遍的,通常,要避免读写冲突,必须保证任何时候仅有一个线程在写入,有线程正在读取的时候,写入操作就必须等待。简单说,就是要避免“写-写”冲突和“读-写”冲突。但是同时读是允许的,因为“读-读”不冲突,而且很安全。 要实现以上的ReadWriteLock,简单的使用synchronized就不行,我们必须自己设计一个ReadWriteLock类,在读之前,必须先获得“读锁”,写之前,必须先获得“写锁”。举例说明: DataHandler对象保存了一个可读写的char[]数组: package com.crackj2ee.thread; public class DataHandler { // store data: private char[] buffer = "AAAAAAAAAA".toCharArray(); 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) {} } } doRead()和doWrite()方法是非线程安全的读写方法。为了演示,加入了sleep(),并设置读的速度大约是写的3倍,这符合通常的情况。 为了让多线程能安全读写,我们设计了一个ReadWriteLock: package com.crackj2ee.thread; public class ReadWriteLock { private int readingThreads = 0; private int writingThreads = 0; private int waitingThreads = 0; // waiting for write private boolean preferWrite = true; public synchronized void readLock() throws InterruptedException { while(writingThreads>0 || (preferWrite && waitingThreads>0)) this.wait(); readingThreads++; } public synchronized void readUnlock() { readingThreads--; preferWrite = true; notifyAll(); } public synchronized void writeLock() throws InterruptedException { waitingThreads++; try { while(readingThreads>0 || writingThreads>0) this.wait(); } finally { waitingThreads--; } writingThreads++; } public synchronized void writeUnlock() { writingThreads--; preferWrite = false; notifyAll(); } }
转载请注明原文地址: https://www.6miu.com/read-5051362.html

最新回复(0)