Read Write Lock 模式

Read Write Lock 模式就是将内容的读取和写入分开进行处理。

因为数据的互斥需要牺牲性能,读的时候可以互不影响,但是读的时候禁止写。

实际案例

类信息概览:

类名 说明
Main.java 方法的总入口
WriterThread.java 写线程
MyReadWriteLock.java 自定义读写锁
ReadWriteLock.java 读写锁
ReaderThread.java 读线程
Data.java 数据对象

定义

  • WriterThread.java
  [java]
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
package com.github.houbb.thread.learn.easy.learn.rwlock; import com.github.houbb.thread.learn.easy.learn.CharUtil; import com.github.houbb.thread.learn.easy.learn.ThreadUtil; public class WriterThread extends Thread { private Data data; public WriterThread(Data data) { super("WriterThread"); this.data = data; } @Override public void run() { while(true) { char c = CharUtil.nextChar(); try { System.out.println(Thread.currentThread().getName() + " writes " + c); data.write(c); } catch (InterruptedException e) { e.printStackTrace(); } ThreadUtil.sleepRandom(); } } }
  • MyReadWriteLock.java
  [java]
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
package com.github.houbb.thread.learn.easy.learn.rwlock; /** * 读写冲突 * 写写冲突 */ public class MyReadWriteLock implements ReadWriteLock { private int readingReaders = 0; //正在读的 private int waitingWriters = 0; //等待写的 private int writingWriters = 0; //正在写的 private boolean preferWriter = true; //写优先 @Override public synchronized void readLock() throws InterruptedException { while(writingWriters > 0 || (preferWriter && waitingWriters > 0)) { wait(); } readingReaders++; //读+1 } @Override public synchronized void readUnLock() { if(readingReaders > 0) { readingReaders--; } preferWriter = true; //优先写 notifyAll(); } @Override public synchronized void writeLock() throws InterruptedException { waitingWriters++; try { while(writingWriters > 0 || readingReaders > 0) { wait(); } } finally { waitingWriters--; } writingWriters++; } @Override public synchronized void writeUnLock() { writingWriters--; preferWriter = false; notifyAll(); } }
  • ReadWriteLock.java
  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.github.houbb.thread.learn.easy.learn.rwlock; public interface ReadWriteLock { void readLock() throws InterruptedException; void readUnLock() throws InterruptedException; void writeLock() throws InterruptedException; void writeUnLock() throws InterruptedException; }
  • ReaderThread.java
  [java]
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
package com.github.houbb.thread.learn.easy.learn.rwlock; import com.github.houbb.thread.learn.easy.learn.ThreadUtil; public class ReaderThread extends Thread { private Data data; public ReaderThread(Data data) { this.data = data; } @Override public void run() { while(true) { try { char[] chars = data.read(); System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(chars)); ThreadUtil.sleepRandom(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
  • Data.java
  [java]
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
package com.github.houbb.thread.learn.easy.learn.rwlock; import com.github.houbb.thread.learn.easy.learn.ThreadUtil; import java.util.Arrays; public class Data { private final int size; private char[] buffer; private final ReadWriteLock readWriteLock = new MyReadWriteLock(); public Data(int size) { this.size = size; buffer = new char[size]; initBuffer(); } private void initBuffer() { Arrays.fill(buffer, '*'); } public char[] read() throws InterruptedException { readWriteLock.readLock(); try { //copy current value char[] result = new char[size]; System.arraycopy(buffer, 0, result, 0, size); ThreadUtil.sleep(50); return result; } finally { readWriteLock.readUnLock(); } } public void write(char c) throws InterruptedException { readWriteLock.writeLock(); //do write try { Arrays.fill(buffer, c); ThreadUtil.sleep(50); } finally { readWriteLock.writeUnLock(); } } }

测试

  • Main.java
  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.github.houbb.thread.learn.easy.learn.rwlock; public class Main { public static void main(String[] args) { Data data = new Data(10); new ReaderThread(data).start(); new ReaderThread(data).start(); new WriterThread(data).start(); } }
  • 测试结果
  [plaintext]

实现方式

UML & Code

UML

Read Write Lock

Code

代码地址

Read Write Lock

系列导航

多线程系列导航