Read—Write Lock Pattern将读写分离,在读取之前,获得用来读取的锁,在写在之前,获得用来写入的锁,
读写的锁的关系是:有人读取(多个也无所谓)时,写不能进行;有人写入时,其他的写和读不能进行。
代码如下:
package readwritelock;
public class Data {
private final char[] buffer;
private final ReadWriteLock readWriteLock = new ReadWriteLock();
public Data(int size){
this.buffer=new char[size];
for (int i = 0; i < buffer.length; i++) {
buffer[i] ='*';
}
}
public char[] read(){
readWriteLock.readLock();
try{
return doRead();
}finally{
readWriteLock.readUnLock();
}
}
public void write(char c){
readWriteLock.writeLock();
try{
doWrite(c);
}finally{
readWriteLock.writeUnLock();
}
}
private char[] doRead(){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return buffer;
}
private void doWrite(char c){
for (int i = 0; i < buffer.length; i++) {
buffer[i] =c;
}
}
}
/*******************************************/
package readwritelock;
public class ReadThread extends Thread {
private Data data;
public ReadThread(Data data) {
this.data = data;
}
public void run() {
while (true) {
char[] c = data.read();
System.out.println(Thread.currentThread().getName() + ": "
+ String.valueOf(c));
}
}
}
/*******************************************/
package readwritelock;
public class ReadWriteLock {
private volatile int readLocks = 0;
private volatile int writeLocks = 0;
private volatile int waitLocks = 0;
private volatile boolean writeFirst =true;
public synchronized void readLock() {
// 写锁或者等待锁大于0,读阻塞
while (writeLocks > 0 || writeFirst&&waitLocks > 0) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
readLocks++;
}
public synchronized void readUnLock() {
readLocks--;
writeFirst =true;
notifyAll();
}
public synchronized void writeLock() {
// 写等待
waitLocks++;
try {
while (readLocks > 0||writeLocks>0) {
wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
waitLocks --;
}
writeLocks++;
}
public synchronized void writeUnLock() {
writeLocks--;
writeFirst =false;
notifyAll();
}
}
/*********************************************/
package readwritelock;
import java.util.Random;
public class WriterThread extends Thread {
private Data data;
private String str;
private int index =0;
public WriterThread(Data data, String str) {
this.data = data;
this.str = str;
}
public void run(){
while(true){
data.write(get());
try {
Thread.sleep(new Random().nextInt(200));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private char get(){
char a =str.charAt(index);
index++;
if(index>=str.length()){
index = 0;
}
return a;
}
}
/*********************************************/
package readwritelock;
public class Test {
public static void main(String[] args) {
Data data = new Data(10);
new WriterThread(data, "asdsad");
new WriterThread(data, "有亲戚吗");
new ReadThread(data).start();
}
}
jdk concurrent 包里面有CurrentHashMap和CopyOnWriteArrayList都有锁的概念
CurrentHashMap有个分离锁,把Map分成几个段,对于一个段的写入,不影响其他段的读写,
CopyOnWriteArrayList可以并发的读取,并且返回一个稳定的迭代器,对于写入,是重新开辟一个数组,拷贝原来的数据进行修改,修改完成后再合并回去.
jdk concurrent的 ReentrantReadWriteLock就是一个可以冲入的读写锁