サンプル
* java.util.concurrent でもっと簡単に書けるらしいが、勉強なので真面目に書くhttp://blogs.yahoo.co.jp/dk521123/32538961.html
Main.java
public class Main {
public static void main(String[] args) {
DataStocker stocker = new DataStocker(10);
new ReaderThread(stocker).start();
new ReaderThread(stocker).start();
new ReaderThread(stocker).start();
new ReaderThread(stocker).start();
new ReaderThread(stocker).start();
new WriterThread(stocker, "ABCDEFGHIJ").start;
new WriterThread(stocker, "0123456789").start;
}
}
DataStocker.java
SharedResourcepublic class DataStocker {
private final char[] targetData; // ここが、読み書き対象のデータ本体
private final ReadWriteLock lock = new ReadWriteLock();
public DataStocker(int size) {
this.targetData = new char[size];
for (int i = 0; i < this.targetData.length; i++) {
this.targetData[i] = '*';
}
}
public List<Person> readData() throws InterruptedException {
this.lock.readLock();
try {
return read();
} finally {
this.lock.readUnlock();
}
}
public void writeData(char value) throws InterruptedException {
this.lock.writeLock();
try {
return write(value);
} finally {
this.lock.writeUnlock();
}
}
private List<Person> read() throws InterruptedException {
char[] newData = new char[this.targetData.lenght];
for (int i = 0; i < this.targetData.length; i++) {
newData[i] = this.targetData[i];
}
this.slow();
return newData;
}
private void write(char value) throws InterruptedException {
for (int i = 0; i < this.targetData.length; i++) {
targetData[i] = value;
this.slow();
}
}
// For Test
private void slow() {
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
ReaderThread.java
Readerpublic class ReaderThread extends Thread {
private final DataStocker stocker;
public WriterThread(DataStocker stocker) {
this.stocker = stocker;
}
public void run() {
try {
while(true) {
char[] readValues = this.stocker.readData();
System.out.println("Result : " + Thread.currentThread().getName() +
" Read Values : " + String.valueOf(readValues));
}
} catch (Exception ex) {
}
}
}
WriterThread.java
Writerpublic class WriterThread extends Thread {
private static final Random random = new Random();
private final DataStocker stocker;
private final String stockData;
private int index = 0;
public WriterThread(DataStocker stocker, String stockData) {
this.stocker = stocker;
this.stockData = stockData;
}
public void run() {
try {
char value = this.nextValue();
this.writeData(value);
Thread.sleep(random.nextInt(3000));
} catch (Exception ex) {
}
}
private char nextValue() {
char value = this.filler.charAt(this.index);
this.index++;
if (this.index >= this.stockData.length()) {
this.index = 0;
}
return value;
}
}
ReadWriteLock.java
ReadWriteLockReentrantLock(再入可能ロック)と同じ?
public final class ReadWriteLock {
private int readingThreadNumber = 0;
private int waitingWriterThreadNumber = 0;
private int writingThreadNumber = 0;
private boolean isReadyForWriter = true;
public synchronized void readLock() throws InterruptedException {
while (this.writingThreadNumber > 0 ||
(this.isReadyForWriter && this.waitingWriterThreadNumber > 0)) {
wait();
}
this.readingThreadNumber++;
}
public synchronized void readUnlock() {
this.readingThreadNumber--;
this.isReadyForWriter = true;
notifyAll();
}
public synchronized void writeLock() throws InterruptedException {
this.waitingWriterThreadNumber++;
try {
while (this.readingThreadNumber > 0 || writingThreadNumber > 0) {
wait();
}
} fianlly {
this.waitingWriterThreadNumber--;
}
this.writingThreadNumber++;
}
public synchronized void writeUnlock() {
this.writingThreadNumber--;
this.isReadyForWriter = false;
notifyAll();
}
}
関連するデザインパターン
Immutable パターン
* 登場人物「Reader」で排他制御をなくするために使用
Single Threaded Execution パターン
* 登場人物「Writer」のスレッドを1個に限定するために使用
Guarded Suspension パターン
* 登場人物「ReadWriteLock」を作る時に使用http://blogs.yahoo.co.jp/dk521123/32928012.html
Before/After パターン
* ロックの解放忘れを防ぐために使用
Strategized Locking パターン
* 排他制御のパフォーマンスにおいて、更に柔軟な排他制御を実現しているらしい。
参考文献
http://pgcafe.moo.jp/JAVA/thread/main_5.htmConcurrentとの性能比較
http://gurimmer.lolipop.jp/daihakken/2012/03/21/javareadwritelock%E3%81%A8concurrent%E3%81%AE%E6%80%A7%E8%83%BD%E6%AF%94%E8%BC%83/ロックについて
http://www.horobi.com/tips/SmartLock/ReentrantLock(再入可能ロック)
http://d.hatena.ne.jp/yone098/20070109/1168321219https://www.ibm.com/developerworks/jp/java/library/j-jtp10264/
http://d.hatena.ne.jp/unageanu/20070419/1176959204