Read-Wirte Lock Pattern
Read-Write Lock Pattern 将读取和写入分开来处理。在读取数据之前,必须获取用来读取的锁定。而要写入的时候,则必须获取用来写入的锁定。因为进行读取时,实例的状态不会改变,所以,就算有多个线程在同时读取也没有关系。但当有线程在进行写入的时候,不可以再进行写入的操作。写入的时候,实例的状态会改变。于是,当有一个线程在写入的时候,其他线程就不可以进行读取或写入。一般来说,进行共享互斥会使程序性能变差,但将写入的共享互斥与读取的共享互斥拆分开来,就可以提高程序的性能
public class ReadWriteLock { /** * 正在读取的线程数 */ private int readingThreadsNumber; /** * 正在写入的线程数(最多为1) */ private int writingThreadsNumber; /** * 等待写入的线程数 */ private int waitingWriteThreadsNumber; /** * 是否优先写入,true:优先写入;false:优先读取 */ private boolean preferWriter = true; public synchronized void readLock() throws InterruptedException { // 如果有线程正在写入或者优先写入时,有线程正在等待写入,读取线程则等待 while (this.writingThreadsNumber > 0 || (this.preferWriter && this.waitingWriteThreadsNumber > 0)) { wait(); } this.readingThreadsNumber++; } public synchronized void readUnlock() throws InterruptedException { this.readingThreadsNumber--; this.preferWriter = true; notifyAll(); } public synchronized void writeLock() throws InterruptedException { this.waitingWriteThreadsNumber++; // 如果有线程正在写入或者正在读取,当前写入线程等待 try { while (this.writingThreadsNumber > 0 || this.readingThreadsNumber > 0) { wait(); } } finally { this.waitingWriteThreadsNumber--; } this.writingThreadsNumber++; } public synchronized void writeUnlock() throws InterruptedException { this.writingThreadsNumber--; this.preferWriter = false; notifyAll(); } }
public class Data { private char[] buffer; private ReadWriteLock readWriteLock = new ReadWriteLock(); public Data(int size) { this.buffer = new char[size]; for (int i = 0; i < size; i++) { this.buffer[i] = '*'; } } public char[] read() throws InterruptedException { try { readWriteLock.readLock(); return doRead(); } finally { readWriteLock.readUnlock(); } } public void write(char c) throws InterruptedException { try { readWriteLock.writeLock(); doWrite(c); } finally { readWriteLock.writeUnlock(); } } private char[] doRead() { char[] newChars = new char[buffer.length]; System.arraycopy(this.buffer, 0, newChars, 0, this.buffer.length); slowly(); return newChars; } private void doWrite(char c) { for (int i = 0; i < this.buffer.length; i++) { this.buffer[i] = c; slowly(); } } private void slowly() { try { Thread.sleep(100); } catch (InterruptedException e) { } } }
import java.util.Random; public class ReaderThread extends Thread { private static final Random random = new Random(); private final Data data; public ReaderThread(Data data) { this.data = data; } @Override public void run() { while (true) { try { char[] c = data.read(); System.out.println(Thread.currentThread().getName() + "reads " + String.valueOf(c)); Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { } } } }
import java.util.Random; public class WriterThread extends Thread { private static final Random random = new Random(); private final Data data; private final String filler; private int index = 0; public WriterThread(Data data, String filler) { this.data = data; this.filler = filler; } @Override public void run() { while (true) { char c = nextChar(); try { data.write(c); Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { } } } private char nextChar() { char c = filler.charAt(index); index++; if (index > filler.length()) { index = 0; } return c; } }
public class MainThread { public static void main(String[] args) { int bufferSize = 10; Data data = new Data(bufferSize); new ReaderThread(data).start(); new ReaderThread(data).start(); new ReaderThread(data).start(); new ReaderThread(data).start(); new ReaderThread(data).start(); new ReaderThread(data).start(); new ReaderThread(data).start(); String filler1 = "abcdefghjklmnopqrstuvwxyz"; String filler2 = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; new WriterThread(data, filler1).start(); new WriterThread(data, filler2).start(); } }单纯使用Single Thread Execution Pattern时,就连read的操作一次也只有一条线程可以执行。如果read操作比较频繁或比较耗时,那使用Read-Write Lock Pattern会比Single Thread Execution Pattern好很多。但因为Read-Write Lock Pattern的程序比Single Thread Execution Pattern实现复杂,如果read操作很简单,那么使用Single Thread Execution Pattern可能性能反而较高。 Read-Write Lock Pattern的优点在于Reader参与者之间不会起冲突。不过,当wirte操作比较频繁时,Writer参与者会经常阻挡Reader参与者的进行,这样就无法展现Read-Write Lock Pattern的优点。
在ReadWriteLock类中,提供了“读访问锁定”和“写访问锁定”两种逻辑上的锁定,但在“物理”上只用到了一个锁定,即ReadWriteLock实例的锁定。
Thread-Per-Message Pattern
待续。。。。
Worker Thread Pattern
待续。。。。
作者:shenzhen_liubin 发表于2013-8-8 23:38:07 原文链接
阅读:83 评论:0 查看评论