看了一个很好的关于读写线程的设计,支持可重入,代码写的很好,优秀的代码总是需要慢慢的专研和学习的,嘿嘿
package com.zcswl.syn;
import java.util.HashMap;
import java.util.Map;
/**
* 读线程不能够阻塞读线程,
* 当前的读线程能够阻塞其他线程的写线程,自身拥有写线程
* 当前的写线程能够阻塞其他线程的读线程,自身拥有读线程,并且可重复获取当前的写线程
* @author zhouchenggong
*
*/
public class ReadWriterLockFinal {
private Map<Thread, Integer> readingThreads =new HashMap<Thread, Integer>();
//读线程Map集合
private int writeAccesses = 0;//写标志
private int writeRequests = 0;//写请求
private Thread writingThread = null;//写线程
public synchronized void lockRead() throws InterruptedException{
Thread callingThread = Thread.currentThread();
while(! canGrantReadAccess(callingThread)){
wait();
}
/**
* 将当前的读线程加入到读线程的Map集合中,设置当前线程在集合中的int值
*/
readingThreads.put(callingThread,
(getReadAccessCount(callingThread) + 1));
}
private boolean canGrantReadAccess(Thread callingThread){
if(isWriter(callingThread)) return true;//如果当前的线程是写线程,不阻塞
if(hasWriter()) return false;//如果存在写线程,阻塞
if(isReader(callingThread)) return true;//如果当前的线程是读线程,不阻塞
if(hasWriteRequests()) return false;//如果当前存在写请求,阻塞
return true;
}
public synchronized void unlockRead(){
Thread callingThread = Thread.currentThread();
if(!isReader(callingThread)){//如果当前的线程不是读线程,非法持有锁异常
throw new IllegalMonitorStateException(
"Calling Thread does not" +
" hold a read lock on this ReadWriteLock");
}
/**
* 在读线程的Map中获取,如果为1,表示的是读写第一次
*/
int accessCount = getReadAccessCount(callingThread);
if(accessCount == 1){
readingThreads.remove(callingThread);
} else {
//Map中没有改线程,加入进去
readingThreads.put(callingThread, (accessCount -1));
}
notifyAll();
}
public synchronized void lockWrite() throws InterruptedException{
writeRequests++;//写请求加一
Thread callingThread = Thread.currentThread();
while(!canGrantWriteAccess(callingThread)){
wait();
}
writeRequests--;
writeAccesses++;
writingThread = callingThread;
}
public synchronized void unlockWrite()
throws InterruptedException{
if(!isWriter(Thread.currentThread())){
throw new IllegalMonitorStateException(
"Calling Thread does not" +
" hold the write lock on this ReadWriteLock");
}
writeAccesses--;
if(writeAccesses == 0){
writingThread = null;
}
notifyAll();
}
private boolean canGrantWriteAccess(Thread callingThread){
if(isOnlyReader(callingThread)) return true;//表示当前的线程是读线程
if(hasReaders()) return false;//存在读线程
if(writingThread == null) return true;//没有写线程
if(!isWriter(callingThread)) return false;//如果当前的线程还是写线程,锁重入,可以再次获取
return true;
}
private int getReadAccessCount(Thread callingThread){
Integer accessCount = readingThreads.get(callingThread);
if(accessCount == null) return 0;
return accessCount.intValue();
}
private boolean hasReaders(){
return readingThreads.size() > 0;
}
private boolean isReader(Thread callingThread){
return readingThreads.get(callingThread) != null;
}
private boolean isOnlyReader(Thread callingThread){
return readingThreads.size() == 1 &&
readingThreads.get(callingThread) != null;
}
//如果写线程不是null,true;
private boolean hasWriter(){
return writingThread != null;
}
//如果当前的线程是写线程,true;
private boolean isWriter(Thread callingThread){
return writingThread == callingThread;
}
private boolean hasWriteRequests(){
return this.writeRequests > 0;
}
}