Java读写锁

Java读写锁,ReadWriteLock.java接口, RentrantReadWriteLock.java实现。通过读写锁,可以实现读-读线程并发,读-写,写-读线程互斥进行。以前面试遇到一个问题,ConcurrentHashMap的实现原理,如何封装Map效率更高。今天看了《Java并发编程实战》,封装的ReadWriteMap类,效率就比ConcurrentHashMap效率更高,在读多写少的场景。

ReadWriteMap.java

 1 public class ReadWriteMap<K, V> {
 2     private final Map<K, V> map;
 3     private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 4     private final Lock readLock = readWriteLock.readLock();
 5     private final Lock writeLock = readWriteLock.writeLock();
 6 
 7     public ReadWriteMap(Map<K, V> map){
 8         this.map = map;
 9     }
10 
11     public V put(K key, V value){
12         writeLock.lock();
13         try{
14             return map.put(key, value);
15         } finally {
16             //释放锁,一定要写在finally里面
17             writeLock.unlock();
18         }
19     }
20 
21     public V get(K key){
22         readLock.lock();
23         try{
24             return map.get(key);
25         } finally {
26             readLock.unlock();
27         }
28     }
29 
30 }

ConcurrentHashMap里面的putVal()方法

 1  /** Implementation for put and putIfAbsent */
 2     final V putVal(K key, V value, boolean onlyIfAbsent) {
 3         if (key == null || value == null) throw new NullPointerException();
 4         int hash = spread(key.hashCode());
 5         int binCount = 0;
 6         for (Node<K,V>[] tab = table;;) {
 7             Node<K,V> f; int n, i, fh;
 8             if (tab == null || (n = tab.length) == 0)
 9                 tab = initTable();
10             else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
11                 if (casTabAt(tab, i, null,
12                              new Node<K,V>(hash, key, value, null)))
13                     break;                   // no lock when adding to empty bin
14             }
15             else if ((fh = f.hash) == MOVED)
16                 tab = helpTransfer(tab, f);
17             else {
18                 V oldVal = null;
19                 synchronized (f) {
20                     if (tabAt(tab, i) == f) {
21                         if (fh >= 0) {
22                             binCount = 1;
23                             for (Node<K,V> e = f;; ++binCount) {
24                                 K ek;
25                                 if (e.hash == hash &&
26                                     ((ek = e.key) == key ||
27                                      (ek != null && key.equals(ek)))) {
28                                     oldVal = e.val;
29                                     if (!onlyIfAbsent)
30                                         e.val = value;
31                                     break;
32                                 }
33                                 Node<K,V> pred = e;
34                                 if ((e = e.next) == null) {
35                                     pred.next = new Node<K,V>(hash, key,
36                                                               value, null);
37                                     break;
38                                 }
39                             }
40                         }
41                         else if (f instanceof TreeBin) {
42                             Node<K,V> p;
43                             binCount = 2;
44                             if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
45                                                            value)) != null) {
46                                 oldVal = p.val;
47                                 if (!onlyIfAbsent)
48                                     p.val = value;
49                             }
50                         }
51                     }
52                 }
53                 if (binCount != 0) {
54                     if (binCount >= TREEIFY_THRESHOLD)
55                         treeifyBin(tab, i);
56                     if (oldVal != null)
57                         return oldVal;
58                     break;
59                 }
60             }
61         }
62         addCount(1L, binCount);
63         return null;
64     }

使用的是synchronized进行同步,synchronized是独占锁,在读多写少的情况下效率不高,极端情况就是所有都是读线程,串行执行。

原文地址:https://www.cnblogs.com/luckygxf/p/7040576.html