原创转载请注明出处: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 ...