zoukankan      html  css  js  c++  java
  • 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是独占锁,在读多写少的情况下效率不高,极端情况就是所有都是读线程,串行执行。

  • 相关阅读:
    POJ2456 Aggressive cows
    Binary Search
    Leetcode1025 Divisor Game
    我的高中生活目标
    leetcode155 min stack
    Leetcode983 Minimum Cost For Tickets
    合并两个有序数组
    X的平方根
    力扣第35场双周赛
    整数反转
  • 原文地址:https://www.cnblogs.com/luckygxf/p/7040576.html
Copyright © 2011-2022 走看看