集合总结 --- 集合同步

集合同步的概念:

  • 比如说现在A线程 和B线程,要拿到这个集合对象,现在集合对象里有 [1,2,3]。那么A在集合对象里添加了一些数字[1,2,3,4,5]。那么这个时候B线程取拿这个集合对象的时候,还是[1,2,3]而不是A已经修改过的集合[1,2,3,4,5]。所以说这里的集合不同步。

https://blog.csdn.net/qq_31156277/article/details/80517483

当多个并发线程向这些集合中存取元素时,就可能破环这些集合的数据完整性 。

实现同步集合的方法:

1、包装线程不安全的集合

缺点:这些集合的效率通常不高

2、线程安全的集合类

java.util.concurrent包下,提供了大量支持高效并发访问的集合接口和实现类,基本可以分为2类:

  • 以Concurrent开头的集合类  (并发写入时有较好的性能)
  • 以CopyOnWrite开头的集合类

以Concurrent开头的集合类

注意1:默认情况下,ConCurrentHashMap支持16个线程并发写入,当超过16个线程并发向该map写入时,可能需要一些线程需要等待。实际上,可通过concurrencyLevel构造参数来支持更多并发写入线程。

注意2:与HashMap等普通集合不同,ConcurrentLinkedQueue 和ConcurrentHashMap支持多线程并发访问,所以当使用迭代器来遍历集合元素时,该迭代器可能不能反映出创建迭代器之后所做的修改,但程序不会抛出任何异常

以CopyOnWrite开头的集合类

CopyOnWriteArrayList集合。它采用了复制底层数组的方式来实现写操作。由于执行写入操作时需要频繁地复制数组,性能比较差。因此CopyOnWriteArrayList适合在读取操作远大于写入操作的场景,例如缓存等。

部分工具类

测试:java.util.Collection包中的并发类测试

public class TestSynchronizedList {

    public static void main(String[] args) {
        HelloThread ht = new HelloThread();

        for (int i = 0; i < 10; i++) {
            new Thread(ht).start();
        }
    }

}

class HelloThread implements Runnable{

    private static List<String> list = Collections.synchronizedList(new ArrayList<String>());


    static{
        list.add("AA");
        list.add("BB");
        list.add("CC");
    }

    @Override
    public void run() {

        Iterator<String> it = list.iterator();

        while(it.hasNext()){
            System.out.println(it.next());

            list.add("AA");
        }

    }

}

输出:
AA
Exception in thread "Thread-0" Exception in thread "Thread-1" java.util.ConcurrentModificationException
AA
AA

 

测试:java.util.concurrent包中的并发类测试

public class TestCopyOnWriteArrayList {
    public static void main(String[] args) {
        HelloThread ht = new HelloThread();

        for (int i = 0; i < 10; i++) {
            new Thread(ht).start();
        }
    }

}

class HelloThread implements Runnable{

    private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

    static{
        list.add("AA");
        list.add("BB");
        list.add("CC");
    }

    @Override
    public void run() {
        Iterator<String> it = list.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
            list.add("AA");
        }
    }

}

输出:
AA
AA
AA
AA
AA
AA
AA
AA
BB
CC
BB
BB
BB
BB
BB
AA
BB
CC
BB
AA
CC
CC
CC
AA
CC
CC
CC
BB
BB
CC
CC
AA

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值