6.7同步容器
同步容器中的方法主要是使用synchronized进行同步,从而保证线程安全。
ArrayList、HashMap、List,Set,Map这些常见的线程不安全类的同步容器分别如下
ArrayList → Vector,Stack
HashMap→ HashTable(key,value不能为null)
Collections.synchronizedXXX(List,Set,Map)
可自行编写代码验证同步容器的线程安全性
不过需要注意的是:即使使用了同步容器,有时候不一定能真正的做到线程安全,
如下代码使用了vector同步容器类,但会出现异常,原因是线程B在获取vector某个元素的时候,该元素可能已被线程A移除:
package com.moluo.concurrency.syncContainer;
import com.moluo.concurrency.annotation.NotThreadSafe;
import java.util.Vector;
@NotThreadSafe
public class VectorExample2 {
public static Vector<Integer> vector = new Vector<>();
public static void main(String[] args) throws InterruptedException {
while (true) {
for (int i = 0; i < 10; i++) {
vector.add(i);
}
Thread thread = new Thread(() -> {
for (int i = 0; i < vector.size(); i++) {
vector.remove(i);
}
});
Thread thread1 = new Thread(() -> {
for (int i = 0; i < vector.size(); i++) {
vector.get(i);
}
});
thread.start();
thread1.start();
}
}
}同时建议:在做遍历的时候,尽量不要做更新操作,不然很可能出问题。如下例:
如果一定要做更新操作,建议在遍历过程中做好标记,等遍历完后,再取出标记值做更新操作
同步容器缺点
同步容器中的方法主要是使用synchronized进行同步,那么势必会带来性能问题。同时我们演示了同步容器不一定能真正的做到线程安全
推荐方式
在实际的项目中,同步容器我们会使用,但已经越来越少了,通常我们会选用并发容器来代替同步容器
Last updated
Was this helpful?