java 非线程安全_java中线程安全和非线程安全的集合

线程安全数组

非线程安全安全

Collection多线程

Vectoride

ArrayList、LinkedListui

HashSet、TreeSetspa

Map.net

HashTable线程

HashMap、TreeMapcode

字符串对象

StringBuffer

StringBuilder

1、ArrayList和vector区别

Vector和ArrayList间惟一的区别就是Vector每一个方法都自带同步机制。

例:好比我要往集合里面加一个元素,又要保证多个线程不会同时调用同一个对象的add()方法,ArrayList里面就要这样写:

ArrayList list = new ArrayList<>();synchronized(list) {

list.add("233");

}

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

Vector list = new Vector<>();

list.add("233");

由于ArrayList的add方法是这样定义的:

public booleanadd(E e) {

ensureCapacityInternal(size+ 1); //Increments modCount!!

elementData[size++] =e;return true;

}

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

public synchronizedbooleanadd(E e) {

modCount++;

ensureCapacityHelper(elementCount+ 1);

elementData[elementCount++] =e;return true;

}

2、HashTable、HashMap、HashSet:

HashTable和HashMap采用的存储机制是同样的,不一样的是:

一、HashMap:

a. 非线程安全;

b. 采用数组方式存储key-value构成的Entry对象,key容许为null,无容量限制;

c. 遍历使用的是Iterator迭代器;

二、HashTable:

a. 线程安全; (对方法加上synchronized)

b. 不管是key仍是value都不容许有null值的存在;在HashTable中调用Put方法时,若是key为null,直接抛出NullPointerException异常;

c. 遍历使用的是Enumeration列举;

三、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中元素不重复的特性。

3、TreeSet、TreeMap:

TreeSet和TreeMap都是彻底基于Map来实现的,而且都不支持get(index)来获取指定位置的元素,须要遍从来获取。另外,TreeSet还提供了一些排序方面的支持,例如传入Comparator实现、descendingSet以及descendingIterator等。

一、TreeSet:

a. 非线程安全

b. 底层基于TreeMap实现,支持排序;

二、TreeMap:

a. 非线程安全;

b. 典型的基于红黑树的Map实现,所以它要求必定要有key比较的方法,要么传入Comparator比较器实现,要么key对象实现Comparator接口;

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

4、StringBuffer和StringBulider:

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串。

它们是字符串变量,是可改变的对象,每当咱们用它们对字符串作操做时,其实是在一个对象上操做的,不像String同样建立一些对象进行操做,因此速度就快了;

一、在执行速度方面的比较:StringBuilder > StringBuffer ;

二、StringBuilder:非线程安全;

三、StringBuffer:线程安全; (对方法加上synchronized)

对于String、StringBuffer和StringBulider三者使用的总结:

1.若是要操做少许的数据:String

2.单线程操做字符串缓冲区下操做大量数据:StringBuilder

3.多线程操做字符串缓冲区下操做大量数据:StringBuffer

非线程安全!=不安全

虽然ArrayList是线程不安全的,但不表明在多线程下不能使用ArrayList,只能使用Vector。

非线程安全并非多线程环境下就不能使用。线程安全问题在于:多线程操做同一个对象。注意是同一个对象。好比最上面那个模拟,就是在主线程中new的一个ArrayList而后多个线程操做同一个ArrayList对象。

若是是每一个线程中new一个ArrayList,而这个ArrayList只在这一个线程中使用,那么确定是没问题的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值