9、java线性安全_同步容器

同步容器

Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch

同步容器Vector   Stack   HashTable

并发容器:ConcurrentHashMap(segment结构的)、CopyOnWriteArrayList

阻塞队列:ArrayBlockingQueue(基于数组)、LinkedBlockingQueue(基于链表)、PriorityBlockingQueue(优先级队列)、DelayQueue(基于PriorityQueue,一种延时阻塞队列)

1、Java非线程安全容器?

Java集合容器框架有4大类:ListSetQueueMap(非线程安全的)

ListSetQueue接口都继承了Collection接口,Map是单独的接口

ListArrayList(源码:桶数组实现)LinkedList(链表。包含栈、队列操作。双向链表,实现了Deque接口)

Queue:DequePriorityQueue

SetHashSetLinkedHashSetTreeSetset源码中包含一个Map

Map:HashMap(解决冲突的方法:链表法Entry链表)、LinkedHashMapTreeMap(红黑树)

2、Java中的同步容器类

(1)Vector  Stack  HashTable(采用synchronized方法同步)

(2)Collections类中提供的静态工厂方法创建的类

Vector与ArrayList

但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。且在对Vector等容器并发的进行迭代修改时,会报ConcurrentModificationException异常,但在并发容器(CopyOnWriteArrayList)中不会。

HashTable与HashMap

Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

StringBuilder与StringBuffer

StringBuilder和StringBuffer的方法是一模一样,就前者是多线程而后者是单线程的。

Stack 继承自Vector 也是线程安全的。

可以由java.util.Collections来创建线程安全的集合,如:

Collections类中有多个静态方法,它们可以获取通过同步方法封装非同步集合而得到的集合:

     public static Collection synchronizedCollention(Collection c)

     public static List synchronizedList(list l)

     public static Map synchronizedMap(Map m)

     public static Set synchronizedSet(Set s)

     public static SortedMap synchronizedSortedMap(SortedMap sm)

     public static SortedSet synchronizedSortedSet(SortedSet ss)

     这些方法基本上返回具有同步集合方法版本的新类。比如,为了创建多线程安全且由ArrayList支持的List,可以使用如下代码:

List list = Collection.synchronizedList(new ArrayList());

ConcurrentModificationException异常

异常发生的原因:

list.remove(integer);//在iterator迭代中,若直接对list进行remove操作则会报异常。因为源码中,list操作的remove会修改modCount(AbstractList类的成员变量),iterator迭代源码中选取next操作时,会先利用checkForComodification()方法判断modCount是否等于expectedModCount,因为list的remove操作使得modCount不等于expectedModCount,所以报错。

关键点就在于:调用list.remove()方法导致modCountexpectedModCount的值不一致。

注意,像使用for-each进行迭代实际上也会出现这种问题。

解决方法:

单线程下,迭代修改时的ConCurrentModificationException异常

iterator.remove();   //因为iterator的remove()方法中有expectedModCount=modCount,这样迭代就不会出错了。

多线程下,迭代修改时的ConCurrentModificationException异常,解决办法:

(1)在使用iterator迭代时使用synchronized或者Lock进行同步

(2)使用并发容器CopyOnWriteArrayList代替ArrayList和Vector

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值