如果多线程并发的访问与一个数据结构,那么很容易破坏一个数据结构。

  例如,一个线程可能要向一个散列表中插入一条数据的过程中,被剥夺了控制权。如果另外一个线程也开始遍历同一个链表,很可能造成混乱,抛出异常或者陷入死循环。这就是为什么HashMap不是线程安全的原因。

一、旧的线程安全的集合

通过同步包装器将集合变成线程安全的:

List<E> synchArrayList = Collections.synchronizedList(new ArrayList<E>());

Map<K,V> synchMap = Collections.synchronizedList(new HasMap<K,V>());

查看源代码可以发现,就是返回了一个Collections的内部类map,这个map中所有方法都使用同步代码块进行了同步操作:

    public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L; private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
} SynchronizedMap(Map<K,V> m, Object mutex) {
this.m = m;
this.mutex = mutex;
} public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
} public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
public V remove(Object key) {
synchronized (mutex) {return m.remove(key);}
}
public void putAll(Map<? extends K, ? extends V> map) {
synchronized (mutex) {m.putAll(map);}
}
public void clear() {
synchronized (mutex) {m.clear();}
}     //省略........
}

最新文章

  1. 整理几种在axure里使页面居中的方法
  2. C# 如何提取SaveFileDialog的保存路径
  3. Hello Spring Framework——源(Resources)
  4. 面试之Java多线程
  5. codepage IMLangCodePages
  6. 【翻译】C# Tips &amp; Tricks: Weak References - When and How to Use Them
  7. react native for Android (make you first android app)
  8. verilog中的有符号数运算
  9. Core ML 机器学习
  10. 关于阮大神的es6标准入门第一章
  11. CentOS7防火墙管理firewalld
  12. 如何在Linux服务器和windows系统之间上传与下载文件
  13. SQLServer之删除索引
  14. 内嵌tomcat最简单用法
  15. 字体图标三种格式区别(Unicode / Font class / Symbol)
  16. EF延迟加载和懒加载
  17. (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
  18. Base64中文乱码的问题
  19. nginx模块学习
  20. Python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序。

热门文章

  1. 安装 vagrant homestead步骤
  2. AWK高端功能-数组
  3. 发现一个很N且免费的html5拓扑图 关系图 生成组件
  4. 【日常训练】Help Chef Gerasim(Codeforces 99B)
  5. Linux命令的那些事(三)
  6. mysql读写分离配置(整理)
  7. gitlab+jenkins持续集成--http方式连接gitlab
  8. React Native移动开发实战-4-Android平台的适配原理
  9. [朴孝敏][Sketch]
  10. PHP 抽象类和接口区别