1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
| import java.util.Random;
class Data { private final char[] buffer; private final ReadWriteLock lock = new ReadWriteLock(); Data(int size) { this.buffer = new char[size]; for(int i = 0; i < size; i++) { buffer[i] = '*'; } }
char[] read() throws InterruptedException { lock.readLock(); try { return doRead(); } finally { lock.readUnlock(); } }
void write(char c) throws InterruptedException { lock.writeLock(); try { doWrite(c); } finally { lock.writeUnlock(); } }
private char[] doRead() { char[] newBuffer = new char[buffer.length]; System.arraycopy(buffer, 0, newBuffer, 0, newBuffer.length); slowly(); return newBuffer; }
private void doWrite(char c) { for(int i = 0; i < buffer.length; i++) { buffer[i] = c; slowly(); } }
private void slowly() { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } }
}
class WriterThread extends Thread { private static final Random random = new Random(); private final Data data; private final String filler; private int index = 0;
WriterThread(Data data, String filler) { this.data = data; this.filler = filler; }
@Override public void run() { try { while(true) { char c = nextChar(); data.write(c); Thread.sleep(random.nextInt(3000)); } } catch (InterruptedException e) { e.printStackTrace(); } }
private char nextChar() { if(index >= filler.length()) { index = 0; } char c = filler.charAt(index); index++; return c; } }
class ReaderThread extends Thread { private final Data data;
ReaderThread(Data data) { this.data = data; }
@Override public void run() { try { while(true) { char[] readBuffer = data.read(); System.out.println(Thread.currentThread().getName() + " read " + String.valueOf(readBuffer)); } } catch (InterruptedException e) { e.printStackTrace(); } } }
class ReadWriteLock { private int readingReaders = 0; private int waitingWriters = 0; private int writingWriters = 0; private boolean preferWriter = true;
synchronized void readLock() throws InterruptedException { while(writingWriters > 0 || (preferWriter && waitingWriters > 0)) { wait(); } readingReaders++; }
synchronized void readUnlock() { readingReaders--; preferWriter = true; notifyAll(); }
synchronized void writeLock() throws InterruptedException{ waitingWriters++; try { while(readingReaders > 0 || writingWriters > 0) { wait(); } } finally { waitingWriters--; } writingWriters++; }
synchronized void writeUnlock() { writingWriters--; preferWriter = false; notifyAll(); } }
public class Test { public static void main(String[] args) { var data = new Data(10); 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 WriterThread(data, "ABCDEF").start(); new WriterThread(data, "abcdef").start(); } }
|