zoukankan      html  css  js  c++  java
  • java8 关于Set集合的线程安全使用

    场景:并发多线程,往Set集合中存放数据时,发现最终的数量结果不对,经过排查,没有使用线程安全的Set导致

    哈哈,不会描述,代码解释一切,下面代码,使用的 Sets.newHashSet() 和 Collections.synchronizedSet(Sets.newHashSet()) 两种方式,来声明一个Set集合,其中第一个不是线程安全,第二个是线程安全

    代码:

     public static void main(String[] args) {
            ExecutorService executor = new ThreadPoolExecutor(
                    10, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(100000), threadFactory);
    
            //放入0-69999数字的字符串,没有重复的
            List<String> numList = Lists.newArrayList();
            for (int i = 0; i < 70000; i++) {
                numList.add(String.valueOf(i));
            }
    
            //将集合按2000一组分隔
            List<List<String>> tmpNumList = ToolsUtil.spliceArrays(numList, 2000);
    
            //多线程运行
            List<Future<Integer>> futureList = new ArrayList<>();
            Set<String> numSet = Sets.newHashSet();
            Set<String> numSyncSet = Collections.synchronizedSet(Sets.newHashSet());
            tmpNumList.forEach(list -> futureList.add(executor.submit(() -> {
                list.forEach(num -> {
                    numSet.add(num);
                    numSyncSet.add(num);
                });
                return 1;
            })));
    
            futureList.forEach(future -> {
                try {
                    future.get();
                } catch (Exception e) {
                    logger.warn("error,", e);
                }
            });
    
            //结果输出
            System.out.println("线程不安全的Set:" + numSet.size());
            System.out.println("线程安全的Set:" + numSyncSet.size());
        }

    控制台输出:(运行多次,线程不安全的数字一直变动,且不正确)

  • 相关阅读:
    校园网络安全CTF 第一题 和 你真了解我吗?
    href="#" 链接到当前页面
    Redis的Set无序集合命令
    Redis的List链表类型命令
    Redis的String、Hash类型命令
    redis2.8.xx安装配置
    ZendFramework安装配置
    复选框的全选、反选
    列表中被点击的行加亮背景色
    SQL中的替换函数replace()使用
  • 原文地址:https://www.cnblogs.com/JoeyWong/p/11971810.html
Copyright © 2011-2022 走看看