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

SynchronizedMap和ConcurrentHashMap有什么区别?

ConcurrentHashMap后者具有更高的并发

SynchronizedMap锁的是整个对象

ConcurrentHashMap锁的是段

 ...
/**
* Maps the specified key to the specified value in this table.
* Neither the key nor the value can be null.
*
* <p>The value can be retrieved by calling the {@code get} method
* with a key that is equal to the original key.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}
* @throws NullPointerException if the specified key or value is null
*/
public V put(K key, V value) {
return putVal(key, value, false);
} /** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
if (fh >= 0) {
binCount = 1;
for (Node<K,V> e = f;; ++binCount) {
K ek;
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
}
Node<K,V> pred = e;
if ((e = e.next) == null) {
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
else if (f instanceof TreeBin) {
Node<K,V> p;
binCount = 2;
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount);
return null;
}
...

Note:

ConcurrentHashMap 的结构示意图

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

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

多读少写

 ...
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
} /**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+len);
Object[] newElements;
int numMoved = len - index;
if (numMoved == 0)
newElements = Arrays.copyOf(elements, len + 1);
else {
newElements = new Object[len + 1];
System.arraycopy(elements, 0, newElements, 0, index);
System.arraycopy(elements, index, newElements, index + 1,
numMoved);
}
newElements[index] = element;
setArray(newElements);
} finally {
lock.unlock();
}
}
...

最新文章

  1. 目标检测方法——SSD
  2. LinqToEntity模糊查询的方法选择
  3. DateTime.Now.ToString() 用法
  4. java多线程-CyclicBarrier
  5. String 去重,区分大小写
  6. adb调试命令详解-2016.02.01
  7. 关于解决 Failed to prepare partial IU:
  8. C程序设计语言练习题1-13
  9. CRM Entity 之Money转string int类型等
  10. oracle归档日志
  11. [Swust OJ 643]--行列式的计算(上三角行列式变换)
  12. hdu1150 Machine Schedule 经典二分匹配题目
  13. Hive如何添加第三方JAR
  14. ES6之Symbol
  15. composer PHP Fatal error致命错误
  16. CentOS6.9切换root用户su root输入正确密码后一直提示Incorrect password,如何解决?
  17. python基本操作
  18. WPF---Binding学习(一)
  19. pip ipython启动错误 Fatal error in launcher: Unable to create process using
  20. spring cloud Eureka常见问题总结

热门文章

  1. Cytoscape基础教程笔记
  2. Jenkins服务配置容易忽略的事项
  3. luogu P3768 简单的数学题 杜教筛 + 欧拉反演 + 逆元
  4. 【BZOJ1801】【DTOJ2004】 [Ahoi2009]chess 中国象棋 【DP】
  5. 51nod 1486 大大走格子(容斥+dp+组合数)
  6. 尽量用类型化的常量替代预处理器的 #DEFINE 方法
  7. 经典JS 判断上传文件大小和JS即时同步电脑时间
  8. js中forEach,for in,for of循环的用法
  9. 重写ArcGIS的TiledMapServiceLayer调用天地图瓦片
  10. s11 day106-107 RBAC模块