• Concurrent


    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11426833.html

    SynchronizedMap和ConcurrentHashMap有什么区别?

    ConcurrentHashMap后者具有更高的并发

    SynchronizedMap锁的是整个对象

    ConcurrentHashMap锁的是段

     1 ...     
     2    /** 
     3      * Maps the specified key to the specified value in this table. 
     4      * Neither the key nor the value can be null. 
     5      * 
     6      * <p>The value can be retrieved by calling the {@code get} method 
     7      * with a key that is equal to the original key. 
     8      * 
     9      * @param key key with which the specified value is to be associated 
    10      * @param value value to be associated with the specified key 
    11      * @return the previous value associated with {@code key}, or 
    12      *         {@code null} if there was no mapping for {@code key} 
    13      * @throws NullPointerException if the specified key or value is null 
    14      */  
    15     public V put(K key, V value) {  
    16         return putVal(key, value, false);  
    17     }  
    18   
    19     /** Implementation for put and putIfAbsent */  
    20     final V putVal(K key, V value, boolean onlyIfAbsent) {  
    21         if (key == null || value == null) throw new NullPointerException();  
    22         int hash = spread(key.hashCode());  
    23         int binCount = 0;  
    24         for (Node<K,V>[] tab = table;;) {  
    25             Node<K,V> f; int n, i, fh;  
    26             if (tab == null || (n = tab.length) == 0)  
    27                 tab = initTable();  
    28             else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {  
    29                 if (casTabAt(tab, i, null,  
    30                              new Node<K,V>(hash, key, value, null)))  
    31                     break;                   // no lock when adding to empty bin  
    32             }  
    33             else if ((fh = f.hash) == MOVED)  
    34                 tab = helpTransfer(tab, f);  
    35             else {  
    36                 V oldVal = null;  
    37                 synchronized (f) {  
    38                     if (tabAt(tab, i) == f) {  
    39                         if (fh >= 0) {  
    40                             binCount = 1;  
    41                             for (Node<K,V> e = f;; ++binCount) {  
    42                                 K ek;  
    43                                 if (e.hash == hash &&  
    44                                     ((ek = e.key) == key ||  
    45                                      (ek != null && key.equals(ek)))) {  
    46                                     oldVal = e.val;  
    47                                     if (!onlyIfAbsent)  
    48                                         e.val = value;  
    49                                     break;  
    50                                 }  
    51                                 Node<K,V> pred = e;  
    52                                 if ((e = e.next) == null) {  
    53                                     pred.next = new Node<K,V>(hash, key,  
    54                                                               value, null);  
    55                                     break;  
    56                                 }  
    57                             }  
    58                         }  
    59                         else if (f instanceof TreeBin) {  
    60                             Node<K,V> p;  
    61                             binCount = 2;  
    62                             if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,  
    63                                                            value)) != null) {  
    64                                 oldVal = p.val;  
    65                                 if (!onlyIfAbsent)  
    66                                     p.val = value;  
    67                             }  
    68                         }  
    69                     }  
    70                 }  
    71                 if (binCount != 0) {  
    72                     if (binCount >= TREEIFY_THRESHOLD)  
    73                         treeifyBin(tab, i);  
    74                     if (oldVal != null)  
    75                         return oldVal;  
    76                     break;  
    77                 }  
    78             }  
    79         }  
    80         addCount(1L, binCount);  
    81         return null;  
    82     }  
    83 ...  

    Note:

    ConcurrentHashMap 的结构示意图

    ConcurrentHashMap 在默认并发级别会创建包含 16 个 Segment 对象的数组。每个 Segment 的成员对象 table 包含若干个散列表的桶。每个桶是由 HashEntry 链接起来的一个链表。如果键能均匀散列,每个 Segment 大约守护整个散列表中桶总数的 1/16。

    CopyOnWriteArrayList可以用于什么应用场景?

    多读少写

     1 ...      
     2    /** 
     3      * Appends the specified element to the end of this list. 
     4      * 
     5      * @param e element to be appended to this list 
     6      * @return {@code true} (as specified by {@link Collection#add}) 
     7      */  
     8     public boolean add(E e) {  
     9         final ReentrantLock lock = this.lock;  
    10         lock.lock();  
    11         try {  
    12             Object[] elements = getArray();  
    13             int len = elements.length;  
    14             Object[] newElements = Arrays.copyOf(elements, len + 1);  
    15             newElements[len] = e;  
    16             setArray(newElements);  
    17             return true;  
    18         } finally {  
    19             lock.unlock();  
    20         }  
    21     }  
    22   
    23     /** 
    24      * Inserts the specified element at the specified position in this 
    25      * list. Shifts the element currently at that position (if any) and 
    26      * any subsequent elements to the right (adds one to their indices). 
    27      * 
    28      * @throws IndexOutOfBoundsException {@inheritDoc} 
    29      */  
    30     public void add(int index, E element) {  
    31         final ReentrantLock lock = this.lock;  
    32         lock.lock();  
    33         try {  
    34             Object[] elements = getArray();  
    35             int len = elements.length;  
    36             if (index > len || index < 0)  
    37                 throw new IndexOutOfBoundsException("Index: "+index+  
    38                                                     ", Size: "+len);  
    39             Object[] newElements;  
    40             int numMoved = len - index;  
    41             if (numMoved == 0)  
    42                 newElements = Arrays.copyOf(elements, len + 1);  
    43             else {  
    44                 newElements = new Object[len + 1];  
    45                 System.arraycopy(elements, 0, newElements, 0, index);  
    46                 System.arraycopy(elements, index, newElements, index + 1,  
    47                                  numMoved);  
    48             }  
    49             newElements[index] = element;  
    50             setArray(newElements);  
    51         } finally {  
    52             lock.unlock();  
    53         }  
    54     }  
    55 ...  
  • 相关阅读:
    css换行
    <a>标签里的<img>标签点击虚线框
    iframe子页面调用父页面元素
    快捷键
    用css绘制三角形
    解决div被embed,object覆盖问题
    一些兼容问题
    兼容padding
    记一次用html2canvas将页面内容生成海报并保存图片到本地
    PUPPETEER安装遇到 ERROR:CHROMIUM REVISION IS NOT DOWNLOADED.的解决办法
  • 原文地址:https://www.cnblogs.com/agilestyle/p/11426833.html
Copyright © 2020-2023  润新知