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

  例如,一个线程可能要向一个散列表中插入一条数据的过程中,被剥夺了控制权。如果另外一个线程也开始遍历同一个链表,很可能造成混乱,抛出异常或者陷入死循环。这就是为什么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();}
}     //省略........
}

Java中线程安全的集合的更多相关文章

  1. java利用线程池处理集合

    java利用线程池处理集合 2018年07月23日 17:21:19 衍夏成歌 阅读数:866   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/s ...

  2. java中线程分两种,守护线程和用户线程。

    java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...

  3. java中线程机制

    java中线程机制,一开始我们都用的单线程.现在接触到多线程了. 多线性首先要解决的问题是:创建线程,怎么创建线程的问题: 1.线程的创建: 四种常用的实现方法 1.继承Thread. Thread是 ...

  4. Java中线程的使用 (2)-多线程、线程优先级、线程睡眠、让步、阻塞

    Java中线程的使用 (2)-多线程.线程优先级.线程睡眠.让步.阻塞 (一)多线程使用方法 说明:创建每个新的线程,一定要记得启动每个新的线程(调用.start()方法) class Xc3 ext ...

  5. Java中线程的实现:

    Java中线程的实现: 一.线程简介: 实现的两种方式为: 1.Thread类 2.Runnable接口 都在java.lang中 都有共通的方法:public void run() 二.线程常用方法 ...

  6. JAVA中线程同步方法

    JAVA中线程同步方法 1  wait方法:         该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所 ...

  7. 多线程(三) java中线程的简单使用

    java中,启动线程通常是通过Thread或其子类通过调用start()方法启动. 常见使用线程有两种:实现Runnable接口和继承Thread.而继承Thread亦或使用TimerTask其底层依 ...

  8. Java中线程池,你真的会用吗?

    在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...

  9. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

随机推荐

  1. Java并发工具类(一):等待多线程完成的CountDownLatch

    作用 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行 简介 CountDownLatch是在java1.5被引入的,存在于java.uti ...

  2. 【SoDiaoEditor电子病历编辑器更新啦】--谨以献给那些还在医疗行业奋斗的小伙伴们

    为什么推荐的人这么少~~~~   更新(2017-4-18): 截止目前已知的已有2个三甲医院在使用该编辑器,容我内心澎湃以下,O(∩_∩)O哈哈~   先放github地址:https://gith ...

  3. TCP协议的特点

    tcp 面向连接,三次握手,创建会话:双向的关闭tcp 可靠性,具备传输确认机制,接收端会对接收到的数据进行ack确认;tcp 具备 rtt (raund动态估算传输时间;tcp 具备超时重传机制tc ...

  4. Cisco Packet Tracer中两台电脑通信设置

    Cisco Packet Tracer是网络初学者仿真模拟网络环境的必备工具.今天我们来模拟下两台电脑之间的通信. Cisco Packet Tracer版本6.2.0 一.添加设备 1.这里添加一个 ...

  5. 【Unity Shader】(七) ------ 复杂的光照(下)

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题.              [Unity Sha ...

  6. Python之元类详解

    一.引子 元类属于Python面向对象编程的深层魔法,99%的人都不得要领,一些自以为搞明白元类的人其实也是自圆其说,点到为止,从队元类的控制上来看就破绽百出,逻辑混乱: 二.什么是元类 一切源自于一 ...

  7. pytorch 如何使用tensorboard实时查看曲线---- tensorboardX简介

    用惯了tensorflow的小伙伴肯定都用过tensorboard工具吧.虽然Facebook也推出了visdom,但是在一次不小心误触clear之后,我放弃了这个工具(页面的一个clear按钮我本来 ...

  8. NO.2:自学tensorflow之路------BP神经网络编程

    引言 在上一篇博客中,介绍了各种Python的第三方库的安装,本周将要使用Tensorflow完成第一个神经网络,BP神经网络的编写.由于之前已经介绍过了BP神经网络的内部结构,本文将直接介绍Tens ...

  9. 深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识

    深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识 在tf第一个例子的时候需要很多预备知识. tf基本知识 香农熵 交叉熵代价函数cross-entropy 卷积神经网络 s ...

  10. webpack入门指南-step02

    webpack 安装 1)安装前的准备:webpack是基于node环境的项目,所以使用前必须先安装node和npm. 在安装 Webpack 前,你本地环境需要支持 node.js.如果电脑没有装过 ...