java5编程(9)java5的线程【锁】与【读写锁_妙用】技术 (六)

2014-11-24 07:45:55 · 作者: · 浏览: 2
er 线程已获得并释放了写入锁之后,该线程才会获得读取锁。

当然,如果等待 writer 放弃其等待,而保留一个或更多 reader 线程为队列中带有写入锁自由的时间最长的 waiter,
则将为那些 reader 分配读取锁。

试图获得公平写入锁的(非重入地)的线程将会阻塞,除非读取锁和写入锁都自由(这意味着没有等待线程)。
(注意,非阻塞 ReentrantReadWriteLock.ReadLock.tryLock() 和 ReentrantReadWriteLock.WriteLock.tryLock() 方法不会遵守此公平设置.
并将获得锁(如果可能),不考虑等待线程)。


重入
此锁允许 reader 和 writer 按照 ReentrantLock 的样式重新获取读取锁或写入锁。
在写入线程保持的所有写入锁都已经释放后,才允许重入 reader 使用它们。

此外,writer 可以获取读取锁,但反过来则不成立。
在其他应用程序中,当在调用或回调那些在读取锁状态下执行读取操作的方法期间保持写入锁时,重入很有用。
如果 reader 试图获取写入锁,那么将永远不会获得成功。

锁降级
重入还允许从写入锁降级为读取锁,
其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。

锁获取的中断
读取锁和写入锁都支持锁获取期间的中断。

Condition 支持 :
写入锁提供了一个 Condition 实现,对于写入锁来说,
该实现的行为与 ReentrantLock.newCondition() 提供的 Condition 实现对 ReentrantLock 所做的行为相同。
当然,此 Condition 只能用于写入锁。

读取锁不支持 Condition,readLock().newCondition() 会抛出 UnsupportedOperationException。

监测 www.2cto.com
此类支持一些确定是保持锁还是争用锁的方法。这些方法设计用于监视系统状态,而不是同步控制。

此类行为的序列化方式与内置锁的相同:反序列化的锁处于解除锁状态,无论序列化该锁时其状态如何。

示例用法。下面的代码展示了如何利用重入来执行升级缓存后的锁降级(为简单起见,省略了异常处理):

*/

class CachedData {
Object data;
volatile boolean cacheva lid;
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

void processCachedData() {
rwl.readLock().lock();
if (!cacheva lid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
// Recheck state because another thread might have acquired
// write lock and changed state before we did.
if (!cacheva lid) {
data = ...
cacheva lid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
rwl.writeLock().unlock(); // Unlock write, still hold read
}

use(data);
rwl.readLock().unlock();
}
}
/*在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。
通常,在预期 collection 很大,读取者线程访问它的次数多于写入者线程,
并且 entail 操作的开销高于同步开销时,这很值得一试。
例如,以下是一个使用 TreeMap 的类,预期它很大,并且能被同时访问。 */

class RWDictionary {
private final Map m = new TreeMap();
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();

public Data get(String key) {
r.lock();
try { return m.get(key); }
finally { r.unlock(); }
}
public String[] allKeys() {
r.lock();
try {
return (String[]) m.keySet().toArray();
}finally {
r.unlock();
}
}
public Data put(String key, Data value) {
w.lock();
try { return m.put(key, value); }
finally { w.unlock(); }
}
public void clear() {
w.lock();
try { m.clear(); }
finally { w.unlock(); }
}
}
/*
实现注意事项:
此锁最多支持 65535 个递归写入锁和 65535 个读取锁。试图超出这些限制将导致锁方法抛出 Error。
*/

读写锁 实现缓存机制


[java]
package com.itm.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class CacheDemo {


private Map cache = new HashMap();

public static void main(String[] args) {


}

/*public synchronized Object getData(String key){
Obje