Read-Write Lock Pattern【读写】
一:Read-Write Lock Pattern的参与者
--->读写锁
--->数据(共享资源)
--->读线程
--->写线程
二Read-Write Lock Pattern模式什么时候使用
--->
* 为了多线线程环境下保护数据安全,我们必须避免的冲突
* 一个线程读取,另一个线程写入的read-write conflick
* 一个线程写入,另一个线程写入的write-write conflick
* 一个线程读取,另一个线程也在读取不会产生冲突
*
* 当线程想要获取读取锁定时:
* -->已经有线程在执行写入,则等待。不等待,则发生read-write conflick
* -->已经有线程在读取,则不需要等待。不存在read-read conflick
*
* 当线程想要获取写入锁定时:
* -->已经有线程在执行写入,则等待。不等待,则发生write-write conflick
* -->已经有线程在执行读取,则等待。不等待,则发生read-write conflick
--->利用同时(读取)不会引起数据冲突的特性,提高系统的性能
--->适合读取操作繁重时
--->适合读取操作比写入操作繁重时
三:Read-Write Lock Pattern思考
--->
四进阶说明
--->
读写锁
/**
*
*/
package com.benxq.thread8;
/**
* 读写锁
* Created by qucf on 2015年10月23日.
*/
public class ReadWriteLock {
//正在读取的线程个数
private Integer readInteger=0;
//正在写入线程的个数(最大为1)
private Integer writeInteger=0;
//正在等待获取写入锁定的线程个数
private Integer writeWaitInteger=0;
//获取写入锁定优先的话 设置为true
private boolean writeBoolean=false;
//获取读取锁的方法
public synchronized void readlock() throws InterruptedException{
//如果有写入操作 写入优先并且有等待写入的线程
while(writeInteger>0 ||(writeWaitInteger>0&&writeBoolean)){
wait();
}
readInteger++;
}
//释放读取锁的方法
public synchronized void readUnLock(){
//读取减1
readInteger--;
//将写入设置优先
writeBoolean=true;
//唤醒所有线程
notifyAll();
}
//获取写入锁定的方法
public synchronized void writeLock() throws InterruptedException{
writeWaitInteger++;
//如果有读线程或者写线程则等待
try {
while(readInteger>0||writeInteger>0){
wait();
}
} finally{
writeWaitInteger--;
}
//写入线程+1
writeInteger++;
}
//释放写入锁
public synchronized void writeUnLock(){
//写入线程数-1
writeInteger--;
//设置优先级为false
writeBoolean=false;
//唤醒所有线程
notifyAll();
}
}
数据类
/**
*
*/
package com.benxq.thread8;
/**
* 数据类
* 持有公共数据+改公共数据的读写锁
* Created by qucf on 2015年10月23日.
*/
public class Data {
//数据类持有的锁
private final ReadWriteLock lock=new ReadWriteLock();
//要访问的公共数据
private final String[] buffer;
public Data(int i) {
buffer=new String[i];
for (int a = 0; a < buffer.length; a++) {
buffer[a]="**";
}
}
public ReadWriteLock getLock() {
return lock;
}
//读取数据的方法
public String[] read() throws InterruptedException{
//获取读取锁
lock.readlock();
try {
Thread.sleep(1000);
return buffer;
} finally{
lock.readUnLock();
}
}
//写入操作
public void write(String a) throws InterruptedException {
//获取写入的suo
lock.writeLock();
try {
Thread.sleep(1000);
doWrite(a);
} finally{
lock.writeUnLock();
}
}
//真正的写操作
public void doWrite(String a){
for (int i = 0; i < buffer.length; i++) {
buffer[i]=a;
}
}
}
读线程
/**
*
*/
package com.benxq.thread8;
/**
* 读线程
* Created by qucf on 2015年10月23日.
*/
public class ReadThread implements Runnable{
private Data data;
public ReadThread(Data data) {
this.data=data;
}
@Override
public void run() {
while(true){
try {
String[] str = data.read();
Thread.sleep(1000);
System.out.println("["+Thread.currentThread().getName()+"]读取数据为:"+str[0]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
写线程
/**
*
*/
package com.benxq.thread8;
/**
* 写线程
* Created by qucf on 2015年10月23日.
*/
public class WriteThread implements Runnable{
private Data data;
public WriteThread(Data data) {
this.data=data;
}
@Override
public void run() {
while(true){
try {
for (int i = 0; i < 10; i++) {
data.write("内容"+i);
Thread.sleep(1000);
System.out.println("["+Thread.currentThread().getName()+"]写入内容为:内容"+i);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
主线程
/**
*
*/
package com.benxq.thread8;
/**
* Created by qucf on 2015年10月23日.
*/
public class Test {
public static void main(String[] args) {
//生命公共数据
Data data=new Data(3);
//生命读取线程
Thread r1=new Thread(new ReadThread(data));
Thread r2=new Thread(new ReadThread(data));
Thread r3=new Thread(new ReadThread(data));
//声明写入线程
Thread w1=new Thread(new WriteThread(data));
Thread w2=new Thread(new WriteThread(data));
Thread w3=new Thread(new WriteThread(data));
r1.start();
r2.start();
r3.start();
w1.start();
w2.start();
w3.start();
}
}