7、ReadWriteLock

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由JVM控制的,我们只要上好相应的锁即可。

如果你的代码只读数据,可以很多人同时读,但是不能同时写,那就上读锁;如果代码修改数据,只能一个人在写,且不能同时读取,

那就上写锁。总之,读的时候上读锁,写的时候上写锁。

 

java.util.concurrent.lock

Interface ReadWriteLock

实现类:

ReentrantReadWriteLock

 

ReadWriteLock实现了两把锁,一把只能进行读操作,一把进行写操作。读锁能够被多个线程拥有,写锁具有排他性。

所有ReadWriteLock的实现必须保证写锁操作对于读锁操作内存的同步(当然拥有写锁时具有排他性,此时只要保证写操作的内存对读操作

保持可见性就可以了,当然也就是所谓的同步了)。通俗点说,一个成功获得读锁的线程能够看到所有先前释放的写锁的更新。

 

读写锁比相互排它锁支持更大的并发量。它利用的一个事实是:同一时间只能有一个线程对共享数据进行更新,但是可以有多个线程对它进行读取。

 

读写锁的实现当然要比互斥锁的实现更难。此时,我们的应用到底是选择互斥锁还是读写锁,取决于我们应用读写操作发生的频率。如果读操作是频繁

发生的,而写操作不那么频繁,那么可以选择读写锁,这样会提高应用的性能;反之,如果我们的应用写操作比较频繁而读操作不那么频繁,并且读操作

是一些短时间的操作,那么就没有必要用到读写锁。

 

利用ReentrantReadWriteLock实现缓存:

 1 class CachedData {
 2     Object data;
 3     volatile boolean cacheValid;
 4     ReentrantReadWriteLock rwl=new ReentrantReadWriteLock();
 5     
 6     void processCachedData() {
 7         rwl.readLock().lock();
 8         if(!cacheValid) {
 9             //在获得写锁之前必须释放读锁
10             rwl.readLock().unlock();
11             rwl.writeLock().lock();
12             
13             //再次检测状态,因为其他线程有可能获得
14             //写锁并且在我们操作之前改变了状态
15             if(!cacheValid) {
16                 //data=....;
17                 cacheValid=true;
18             }
19             //在释放写锁之前通过获得读锁进行降级
20             rwl.readLock().lock();
21             rwl.writeLock().unlock();//释放写锁仍然拥有读锁
22         }
23         use(data);
24         rwl.readLock().unlock();
25     }
26 }

 

利用ReentrantReadWriteLock提供集合的并发性能:

 1 class RWDictionary {
 2         private final Map<String,Data> m=new TreeMap<String,Data>();
 3         private final ReentrantReadWriteLock rwl=new ReentrantReadWriteLock();
 4         private final Lock r=rwl.readLock();
 5         private final Lock w=rwl.writeLock();
 6         
 7         public Data get(String key) {
 8             r.lock();
 9             try {
10                 return m.get(key);
11             }finally {
12                 r.unlock();
13             }
14         }
15         
16         public String[] allKeys() {
17             r.lock();
18             try {
19                 return (String[])m.keySet().toArray();
20             }finally {
21                 r.unlock();
22             }
23         }
24         
25         public Data put(String key,Data value) {
26             w.lock();
27             try {
28                 return m.put(key, value);
29             }finally {
30                 w.unlock();
31             }
32         }
33         
34         public void clear() {
35             w.lock();
36             try {
37                 m.clear();
38             }finally {
39                 w.unlock();
40             }
41         }
42     }

 

posted on 2015-05-28 09:07  飞机说之代码也疯狂  阅读(154)  评论(0编辑  收藏  举报