考試指導:java多線程設計模式詳解之四

字號:

ReadWriteLock
     多線程讀寫同一個對象的數(shù)據(jù)是很普遍的,通常,要避免讀寫沖突,必須保證任何時候僅有一個線程在寫入,有線程正在讀取的時候,寫入操作就必須等待。
    簡單說,就是要避免“寫-寫”沖突和“讀-寫”沖突。但是同時讀是允許的,因為“讀-讀”不沖突,而且很安全。
     要實現(xiàn)以上的ReadWriteLock,簡單的使用synchronized就不行,我們必須自己設計一個ReadWriteLock類,在讀之前,必須先獲得“讀鎖”,寫之前,必須先獲得“寫鎖”。舉例說明:
    DataHandler對象保存了一個可讀寫的char[]數(shù)組:
    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 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[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--;