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 ...  

 

 

posted @ 2019-08-28 22:06  李白与酒  阅读(270)  评论(0编辑  收藏  举报