防火毯 玻璃纤维耐碱:高性能锁ReentrantReadWriteLock

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 18:59:01

多线程读取并修改一个资源时,我们过去通常使用synchronized同步锁,这个是有性能损失的,很多情况下:资源对象总是被大量并发读取,偶尔有一个线程进行修改,也就是说:以读为主,修改不是很频繁,那么我们在JDK5.0中用ReentrantReadWriteLock就获得比synchronized更高并发性能,高并发性能是我使用JDK5.0主要目的,而不是annotation和泛型等设计优点。

ReentrantReadWriteLock被大量使用在缓存中,因为缓存中的对象总是被共享大量读操作,偶尔修改这个对象中的子对象,比如状态,那么只要通过ReentrantReadWriteLock来更新子对象就可以了,这就实现了Evans DDD中对不变性的要求,我们可以使用ReentrantReadWriteLock对根对象中生命周期短的子对象在内存中直接更新,不必依赖数据库锁,这又是一个摆脱数据库锁的进步。

JiveJdon为例子,ForumThread 通常情况下保存在缓存中,而且是一个单例,那么并发多次请求访问缓存中ForumThread。

ForumThread中有ForumThreadState,根据Evans DDD将经常变换的对象生命周期和其他不变量区分开来,这样,需要修改时不必锁住整个根对象,在DDD一书中,锁住整个子对象是通过数据库锁来实现,而JiveJdon中,我们的对象在缓存中,也必须有一个机制来实现这种细腻度锁。见“实战DDD
http://www.jdon.com/mda/ddd.html

这个状态子对象是每发一个贴就要更新修改的,而平时ForumThreadState 和ForumThread大量被读取,只有回帖者一个请求进行修改,为使其他人立即看到帖子更新,原先需要使用synchronized,但性能影响,现在就可以使用ReentrantReadWriteLock


protected final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
protected final Lock read = readWriteLock.readLock();
protected final Lock write = readWriteLock.writeLock();

public ForumThreadState getState() {
read.lock();
try {
return state;
} finally {
read.unlock();
}
}
/**
* @param forumThreadState The forumThreadState to set.
*/

public void setState(ForumThreadState forumThreadState) {
write.lock();
try {
this.state = forumThreadState;
} finally {
write.unlock();
}

}


为什么要用synchronized?不用synchronized你的对象中数据被修改后,无法使其他线程更新。
http://www.ibm.com/developerworks/java/library/j-praxis/pr50.html

ReentrantReadWriteLock案例
http://ilkinbalkanay.blogspot.com/2008/01/readwritelock-example-in-java.html

ReentrantReadWriteLock原理
http://java.dzone.com/news/java-concurrency-read-write-lo?page=0,0

[该贴被banq于2008-10-17 22:36修改过]