线程安全

非线程安全

Collection

Vector

ArrayList、LinkedList

HashSet、TreeSet

Map

HashTable

HashMap、TreeMap

字符串

StringBuffer

StringBuilder

一、ArrayList和vector区别
Vector和ArrayList间唯一的区别就是Vector每个方法都自带同步机制。
例:比如我要往集合里面加一个元素,又要保证多个线程不会同时调用同一个对象的add()方法,ArrayList里面就要这样写:

ArrayList<String> list = new ArrayList<>();
synchronized (list) {
list.add("233");
}

而Vector里面只要这样写就行了:

Vector<String> list = new Vector<>();
list.add("233");

因为ArrayList的add方法是这样定义的:

    public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

而Vector的add方法是这样定义的:

    public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}

二、HashTable、HashMap、HashSet:
HashTable和HashMap采用的存储机制是一样的,不同的是:
1、HashMap:
a. 非线程安全;
b. 采用数组方式存储key-value构成的Entry对象,key允许为null,无容量限制;
c. 遍历使用的是Iterator迭代器;

2、HashTable:
a. 线程安全; (对方法加上synchronized
b. 无论是key还是value都不允许有null值的存在;在HashTable中调用Put方法时,如果key为null,直接抛出NullPointerException异常;
c. 遍历使用的是Enumeration列举;

3、HashSet:
a. 非线程安全
b. 底层通过HashMap实现,无容量限制;
c. 不保证数据的有序;

在HashSet中,元素都存到HashMap键值对的Key上面,而Value是统一的值private static final Object PRESENT = new Object();,(定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。)
HashSet的add(E e)底层实现调用hashmap的put(E e),将该元素作为key放入HashMap。
由于HashMap的put()方法添加key-value对时,当新放入HashMap的Entry中key与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true), 新添加的Entry的value会将覆盖原来Entry的value,但key不会有任何改变, 因此如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中, 原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性。

HashSet参考:http://zhangshixi.iteye.com/blog/673143

三、TreeSet、TreeMap:
TreeSet和TreeMap都是完全基于Map来实现的,并且都不支持get(index)来获取指定位置的元素,需要遍历来获取。另外,TreeSet还提供了一些排序方面的支持,例如传入Comparator实现、descendingSet以及descendingIterator等。
1、TreeSet:
a. 非线程安全
b. 底层基于TreeMap实现,支持排序;

2、TreeMap:
a. 非线程安全;
b. 典型的基于红黑树的Map实现,因此它要求一定要有key比较的方法,要么传入Comparator比较器实现,要么key对象实现Comparator接口;

与hashmap相比,treemap内部的元素都是排序的,当需要查找某些元素以及顺序输出元素的时候占优势。因此,TreeMap是一个内部元素排序版的HashMap

四、StringBuffer和StringBulider:
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串。
它们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了;
1、在执行速度方面的比较:StringBuilder > StringBuffer ;
2、StringBuilder:非线程安全;
3、StringBuffer:线程安全; (对方法加上synchronized
 
对于String、StringBuffer和StringBulider三者使用的总结:
1.如果要操作少量的数据:String
2.单线程操作字符串缓冲区下操作大量数据:StringBuilder
3.多线程操作字符串缓冲区下操作大量数据:StringBuffer

非线程安全!=不安全
虽然ArrayList是线程不安全的,但不代表在多线程下不能使用ArrayList,只能使用Vector。
非线程安全并不是多线程环境下就不能使用。线程安全问题在于:多线程操作同一个对象。注意是同一个对象。比如最上面那个模拟,就是在主线程中new的一个ArrayList然后多个线程操作同一个ArrayList对象。
如果是每个线程中new一个ArrayList,而这个ArrayList只在这一个线程中使用,那么肯定是没问题的。

参考:
https://blog.csdn.net/u011389474/article/details/54602812
https://www.zhihu.com/question/49855966

最新文章

  1. 虚拟机linux上网问题
  2. MySQL 5.6 for Windows 解压缩版配置安装
  3. linux-impdp的使用
  4. opencv2学习:计算协方差矩阵
  5. 统计fastq文件中读段的数量
  6. CentOS 5.x版本升级PHP
  7. php相关学习资源
  8. Unity3D中关于场景销毁时事件调用顺序的一点记录
  9. JavaScripts学习日记——BOM
  10. 无法识别的配置节 system.serviceModel
  11. 验证浏览器是否安装已flash插件的js脚本
  12. Python做的第一个小项目-模拟登陆
  13. springboot引用dubbo的方式
  14. [R]R包版本更迭【持续更新】
  15. Java基础总结1
  16. The type javax.servlet.http.HttpServletRequest cannot be resolved. It is indirectly referenced from required .class files
  17. centos7和centos6的区别【转】
  18. oracle 对表赋权限
  19. 20.Scrapy日常练手
  20. 【Android】6.3 ProgressDialog

热门文章

  1. 用Qt程序打开.txt 文件的时候,出现乱码的情况
  2. Android学习之基础知识八—Android广播机制实践(实现强制下线功能)
  3. 分布式RPC框架性能大比拼 dubbo、motan、rpcx、gRPC、thrift的性能比较
  4. Spring Boot 之属性读写详解
  5. Linux集锦
  6. phpstorm 2018.1.2的安装和破解
  7. 如何使用 GroupBy 计数-Count()
  8. [Spark][Python]DataFrame select 操作例子II
  9. 递归遍历对象获取value值
  10. Ionic 入门与实战之第二章第一节:Ionic 环境搭建之开发环境配置