Java实现多线程读写数据
实现需求如下:
当数据没有写线程修改数据时,可以多个读线程读取数据。
当数据有写线程修改数据时,读线程等待,其他写线程也等待,只能有一个写线程修改数据。
当数据没有读线程读数据时,可以有一个写线程修改数据。
当数据有读线程读数据时,写线程不能修改数据。
设计如下:
Data:数据类,用于读写数据的类
ReadWriteLock:读写锁类,实现读写锁控制
ReaderThread:读线程,负责读取数据
WriterThread:写线程,负责写数据
Main:main类
实现如下:
Data:数据类
ReadWriteLock:读写锁类
ReaderThread:读线程类
WriterThread:写线程类
Main:main类
执行结果:
实现需求如下:
当数据没有写线程修改数据时,可以多个读线程读取数据。
当数据有写线程修改数据时,读线程等待,其他写线程也等待,只能有一个写线程修改数据。
当数据没有读线程读数据时,可以有一个写线程修改数据。
当数据有读线程读数据时,写线程不能修改数据。
设计如下:
Data:数据类,用于读写数据的类
ReadWriteLock:读写锁类,实现读写锁控制
ReaderThread:读线程,负责读取数据
WriterThread:写线程,负责写数据
Main:main类
实现如下:
Data:数据类
package com.thread.readwriter;
/**
* 数据类
* @author Administrator
*
*/
public class Data {
//写入数据缓存区
private char[] buffer = new char[10];
//数据的读写锁
private final ReadWriteLock lock = new ReadWriteLock();
/**
* 读取数据
* @return
* @throws InterruptedException
*/
public char[] read() throws InterruptedException{
lock.readLock();
try {
char[] buffer = doRead();
System.out.println(Thread.currentThread().getName()+" read "+String.valueOf(buffer));
return buffer;
} finally {
lock.readUnlock();
}
}
/**
* 以字符为单位一次一次的读取缓冲区的数据
* @return
*/
public char[] doRead(){
char[] newbuffer = new char[buffer.length];
for (int i = 0; i < buffer.length; i++) {
newbuffer[i] = buffer[i];
}
return buffer;
}
/**
* 写入缓冲区数据
* @param c
* @throws InterruptedException
*/
public void write(char c) throws InterruptedException{
lock.writeLock();
try {
System.out.println(Thread.currentThread().getName()+" write "+c);
doWrite(c);
} finally {
lock.writeUnlock();
}
}
/**
* 以字符为单位一次一次地写入缓冲区
* @param c
*/
public void doWrite(char c){
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
}
}
}
ReadWriteLock:读写锁类
package com.thread.readwriter;
/**
* 读写锁类
* @author Administrator
*
*/
public class ReadWriteLock {
private int readingNum = 0; //正在读数据的线程数
private int writingNum = 0; //正在写数据的线程数
private int waitingNum = 0; //正在等待写数据的线程数
private boolean writerPriority = true; //写数据优先
/**
* 读数据上锁
* @throws InterruptedException
*/
public synchronized void readLock() throws InterruptedException{
while(writingNum > 0 || (waitingNum > 0 && writerPriority)){
wait();
}
readingNum++;
}
/**
* 读数据解锁
*/
public synchronized void readUnlock(){
readingNum--;
writerPriority = true;
notifyAll();
}
/**
* 写数据上锁
* @throws InterruptedException
*/
public synchronized void writeLock() throws InterruptedException{
waitingNum++;
while(readingNum > 0 || writingNum >0 ){
try {
wait();
} finally {
waitingNum--;
}
}
writingNum++;
}
/**
* 写数据解锁
*/
public synchronized void writeUnlock(){
writingNum--;
writerPriority = false;
notifyAll();
}
}
ReaderThread:读线程类
package com.thread.readwriter;
import java.util.Random;
public class ReaderThread extends Thread{
//数据
private final Data data;
//随机数
private final Random random = new Random();
/**
* 读线程构造方法
* @param name 线程名称
* @param data 注入需要读的数据
*/
public ReaderThread(String name, Data data){
super(name);
this.data = data;
}
/**
* 读取数据
*/
public void run(){
while(true){
try {
data.read();
Thread.sleep(random.nextInt(500));//随机休息
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
WriterThread:写线程类
package com.thread.readwriter;
/**
* 写入线程类
* @author Administrator
*
*/
public class WriterThread extends Thread{
//数据
private final Data data;
//写入字符串
private final String str;
//写字符串下标
private int index = 0;
/**
* 写入线程构造方法
* @param name 线程名称
* @param data 数据存储区
* @param str 写入字符串
*/
public WriterThread(String name, Data data, String str){
super(name);
this.data = data;
this.str = str;
}
/**
* 写入字符串
*/
public void run(){
while(true){
try {
char c = nextChar();
data.write(c);
Thread.sleep(3000); //随机休息
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 循环从字符串中获取字符
* @return
*/
private char nextChar(){
char c = str.charAt(index);
index++;
if(index >= str.length()){
index = 0;
}
return c;
}
}
Main:main类
package com.thread.readwriter;
/**
* main类
* @author Administrator
*
*/
public class Main {
public static void main(String[] args) {
//数据区
Data data = new Data();
//启动写线程
new WriterThread("WriterThread.1", data, "abcdefghijklmnopkrstuvwxyz").start();
new WriterThread("WriterThread.2", data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ").start();
//启动读线程
new ReaderThread("ReaderThread.1", data).start();
new ReaderThread("ReaderThread.2",data).start();
new ReaderThread("ReaderThread.3",data).start();
new ReaderThread("ReaderThread.4",data).start();
}
}
执行结果:
WriterThread.1 write a
WriterThread.2 write A
ReaderThread.2 read AAAAAAAAAA
WriterThread.2 write B
ReaderThread.2 read BBBBBBBBBB
WriterThread.1 write b
ReaderThread.4 read bbbbbbbbbb
WriterThread.2 write C
ReaderThread.4 read CCCCCCCCCC
ReaderThread.2 read CCCCCCCCCC
WriterThread.1 write c
ReaderThread.3 read cccccccccc
WriterThread.2 write D
ReaderThread.2 read DDDDDDDDDD
WriterThread.1 write d
ReaderThread.1 read dddddddddd
WriterThread.2 write E
ReaderThread.1 read EEEEEEEEEE
WriterThread.1 write e
ReaderThread.4 read eeeeeeeeee
WriterThread.1 write f
WriterThread.2 write F
ReaderThread.1 read FFFFFFFFFF
ReaderThread.4 read FFFFFFFFFF
。。