ArrayList、Vector、CopyOnWriteList

两个线程,同时操作一个List,会发生什么?

public static void main(String[] args) {

    // 初始化一个list,放入5个元素
    final List<Integer> list = new ArrayList<>();
    for(int i = 0; i < 5; i++) {
        list.add(i);
    }

    // 线程一:通过Iterator遍历List
    new Thread(new Runnable() {
        @Override
        public void run() {
            for(int item : list) {
                System.out.println("遍历元素:" + item);
                try {
                    Thread.sleep(1000);// 由于程序跑的太快,这里sleep了1秒来调慢程序的运行速度
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();

    // 线程二:remove一个元素
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);// 由于程序跑的太快,这里sleep了1秒来调慢程序的运行速度
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            list.remove(4);
            System.out.println("list.remove(4)");
        }
    }).start();
}

 

1、ArrayList

ArrayList非线程安全,当线程一遍历的时候,线程二正在删除一个元素,线程一遍历不到该元素。
2、Vector

线程安全的Vector,内部很多方法,如add()、remove()、set()、get()、forEach()等都加上了synchronized来进行线程同步,代码如下:

list.forEach(item -> {
    System.out.println("遍历元素:" + item);
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});

 

但如果用for(int item : list)来遍历,需手动同步,代码如下:

synchronized (list) {
    for(int item : list) {
        System.out.println("遍历元素:" + item);
        // 由于程序跑的太快,这里sleep了1秒来调慢程序的运行速度
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

3、CopyOnWriteList

CopyOnWriteArrayList是java.util.concurrent包中的一个List的实现类。CopyOnWrite的意思是在写时拷贝,也就是如果需要对CopyOnWriteArrayList的内容进行改变,首先会拷贝一份新的List并且在新的List上进行修改,最后将原List的引用指向新的List。

使用CopyOnWriteArrayList可以线程安全地遍历,因为如果另外一个线程在遍历的时候修改List的话,实际上会拷贝出一个新的List上修改,而不影响当前正在被遍历的List。
4、工具类Collections使容器线程安全

//make thread-safe list
 List MyStrList = Collections.synchronizedList(new ArrayList());
 MyStrList.add("123");
 MyStrList.add("abc");

 //make thread-safe hashset
 Set set=Collections.synchronizedSet(new HashSet());
 set.add(123);
 set.add(456);

 //make thread-safe hashmap
 Map map=Collections.synchronizedMap(new HashMap());
 map.put(1, "thb");
 map.put(12, "bill tang");

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值