概述
多线程读写锁分离模式
定义共享数据缓存区buffer,有线程往缓存区写数据,有线程从缓存区读取数据,读写锁分离
读写锁:为了更高效的读写数据,将锁分为两种,读数据是读锁,可以并行化多线程执行,写数据是写锁,只能串行化。
READ | Write | |
---|---|---|
READ | N | Y |
Write | Y | Y |
读写锁ReadWriteLock
/**
* @ClassName:ReadWriteLock
* @Author:linianest
* @CreateTime:2020/3/24 11:06
* @version:1.0
* @Description TODO: 读写锁
*/
/**
* 可以并行多线读,如果是写线程操作,写的线程每次只允许一个
*/
public class ReadWriteLock {
// 正在读
private int readingReaders = 0;
// 等待读
private int waitingReaders = 0;
// 正在写
private int writingwriters = 0;
// 等待写
private int waitingwriters = 0;
private boolean preferWriter = true;
public ReadWriteLock() {
this(true);
}
public ReadWriteLock(boolean preferWriter) {
this.preferWriter = preferWriter;
}
/**
* 读锁:如果有线程正在写,那么就wait
*
* @throws InterruptedException
*/
public synchronized void readLock() throws InterruptedException {
// 有线程在准备读
this.waitingReaders++;
try {
// 有线程正在写
while (writingwriters > 0 || (preferWriter && waitingwriters > 0)) {
this.wait();
}
// 现在正在读
this.readingReaders++;
} finally {
// 线程读完了
this.waitingReaders--;
}
}
/**
* 释放读锁
*/
public synchronized void readUnlock() {
this.readingReaders--;
this.notifyAll();
}
/**
* 写锁:如果有线程在读或者在写,那么就wait
*
* @throws InterruptedException
*/
public synchronized void writeLock() throws InterruptedException {
this.waitingwriters++;
try {
while (readingReaders > 0 || writingwriters > 0) {
this.wait();
}
this.writingwriters++;
} finally {
this.waitingwriters--;
}
}
/**
* 释放写锁
*/
public synchronized void writeUnlock() {
this.writingwriters--;
this.notifyAll();
}
}
读写缓冲区:共享资源
package com.ln.concurrent.chapter6;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter6
* @version: 1.0
*/
/**
* @ClassName:SharedData
* @Author:linianest
* @CreateTime:2020/3/24 11:35
* @version:1.0
* @Description TODO: 定义共享数据缓存区buffer,有线程往缓存区写数据,有线程从缓存区读取数据
*/
public class SharedData {
private final char[] buffer;
private final ReadWriteLock lock = new ReadWriteLock();
public SharedData(int size) {
this.buffer = new char[size];
for (int i = 0; i < buffer.length; i++) {
this.buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
try {
lock.readLock();
return this.doRead();
} finally {
lock.readUnlock();
}
}
public void write(char c) throws InterruptedException {
try {
lock.writeLock();
this.doWrite(c);
} finally {
lock.writeUnlock();
}
}
private void doWrite(char c) {
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
slowly(10);
}
}
private char[] doRead() {
char[] newBuf = new char[buffer.length];
for (int i = 0; i < buffer.length; i++) {
newBuf[i] = buffer[i];
}
slowly(50);
return newBuf;
}
private void slowly(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
多线程写数据
/**
* @ClassName:WriterWorker
* @Author:linianest
* @CreateTime:2020/3/24 16:29
* @version:1.0
* @Description TODO: 多线程读数据
*/
public class WriterWorker extends Thread {
private static final Random random = new Random(System.currentTimeMillis());
private final SharedData data;
private final String filler;
private int index = 0;
public WriterWorker(SharedData 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(1_000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private char nextChar() {
char c = filler.charAt(index);
index++;
if (index >= filler.length())
index = 0;
return c;
}
}
多线程写数据
package com.ln.concurrent.chapter6;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter6
* @version: 1.0
*/
import java.util.Random;
/**
* @ClassName:ReadWorker
* @Author:linianest
* @CreateTime:2020/3/24 17:18
* @version:1.0
* @Description TODO: 多线程写数据
*/
public class ReadWorker extends Thread {
private final SharedData data;
public ReadWorker(SharedData data) {
this.data = data;
}
@Override
public void run() {
try {
while (true) {
char[] readBuf = data.read();
System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
多线程读写客户端
package com.ln.concurrent.chapter6;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter6
* @version: 1.0
* @ClassName:ReadWritLockClient
* @Author:linianest
* @CreateTime:2020/3/24 17:24
* @version:1.0
* @Description TODO: 读写锁
*/
/**
*@ClassName:ReadWritLockClient
*@Author:linianest
*@CreateTime:2020/3/24 17:24
*@version:1.0
*@Description TODO: 读写锁设计模式
*/
/**
* ReadWriteLock design pattern
* Reader-Writer design pattern
*/
public class ReadWritLockClient {
public static void main(String[] args) {
final SharedData sharedData = new SharedData(10);
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new WriterWorker(sharedData, "sdfaSDFWEFASewd").start();
new WriterWorker(sharedData, "werewkjSDFSDFWflksd").start();
}
}
最后
以上就是健忘海燕为你收集整理的多线程设计模式-多线程读写锁分离模式的全部内容,希望文章能够帮你解决多线程设计模式-多线程读写锁分离模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复