• 验证HashSet和HashMap不是线程安全


    JAVA集合类:
    java.util包下的HashSet和HashMap类不是线程安全的,
    java.util.concurrent包下的ConcurrentHashMap类是线程安全的。

    写2个测试类来验证下:

    package com.cdfive.learn.thread;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 验证HashSet不是线程安全
     *
     * @author cdfive
     * @date 2019-02-11
     */
    public class HashSetTest {
        public static void main(String[] args) {
            final Set<Integer> set = new HashSet<>();// 结果可能大于1000
    //        final Set<Integer> set = Collections.synchronizedSet(new HashSet<>());// 结果等于1000
    //        final Set<Integer> set = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());// 结果等于1000
    
            // 往set写入1-1000
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <= 1000; i++) {
                        set.add(i);
                    }
                }
            };
    
            int threadNum = 10;// 线程数
            List<Thread> threadList = new ArrayList<>();
            for (int i = 0; i < threadNum; i++) {
                Thread thread = new Thread(runnable);
                threadList.add(thread);
                thread.start();
            }
    
            // 主线程等待子线程执行完成
            for (Thread thread : threadList) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            System.out.println(set.size());// 结果可能大于1000
        }
    }
    
    package com.cdfive.learn.thread;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 验证HashMap不是线程安全
     *
     * @author cdfive
     * @date 2019-02-11
     */
    public class HashMapTest {
        public static void main(String[] args) {
            final Map<Integer, Integer> map = new HashMap<>();// 结果可能大于1000
    //        final Map<Integer, Integer> map = Collections.synchronizedMap(new HashMap<>());// 结果等于1000
    //        final Map<Integer, Integer> map = new ConcurrentHashMap<>();// 结果等于1000
    
            // 往map写入1-1000, key和value相同
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <= 1000; i++) {
                        map.put(i, i);
                    }
                }
            };
    
            int threadNum = 2;// 线程数
            List<Thread> threadList = new ArrayList<>();
            for (int i = 0; i < threadNum; i++) {
                Thread thread = new Thread(runnable);
                threadList.add(thread);
                thread.start();
            }
    
            // 主线程等待子线程执行完成
            for (Thread thread : threadList) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            System.out.println(map.size());// 结果可能大于1000
        }
    }
    

    如果需要保证线程安全的场景:
    1.将HashSet或HashMap转换为线程安全,使用Collections.synchronizedSet或Collections.synchronizedMap方法;
    2.使用Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>())或使用java.util.concurrent包下的ConcurrentHashMap;
    3.仍然使用HashSet或HashMap,使用时手动进行加锁或同步;// 注意加锁粒度,尽可能保证性能

    在项目中根据实际场景进行选择和应用。

  • 相关阅读:
    油管上有多乱!!!这就是美国所谓的“言论自由”
    Gitee官网大规模封禁开源项目,如想解禁则需手动提交审核,在此过程中一些项目的信息也被gitee官方修改!!!
    再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(1) —— Firefox浏览器下自动运行游戏篇 (续)
    ubuntu环境下boost库的安装——Could NOT find Boost (missing: Boost_INCLUDE_DIR program_options) (Required is at least version "1.49.0")
    【转载】 Makefile的静态模式%.o : %.c
    任意界面调出微信的快捷键
    windows cmd切换目录
    w10 本地邮箱同步163,出现可能需要更新密码或授予账户同步到此设备的权限
    yaml有没有多行注释的方法
    笔记本电脑选购显示器
  • 原文地址:https://www.cnblogs.com/cdfive2018/p/10361300.html
Copyright © 2020-2023  润新知