Java HashSet线程不安全

描述

验证 Java HashSet 是否线程安全 。

题目

创建两个线程 往 Java HashSet 集合 中添加元素,验证 Java HashSet 是否线程安全。

题目解决思路

  1. 创建一个实现 Runnable 接口的类,该类添加元素到 HashSet 集合。
  2. 分别创建两个线程,分别添加 1000 个元素到集合中。
  3. 打印集合长度。

代码具体实现

MyRunnable 代码:

public class MyRunnable implements Runnable { private int start; private int end; public static Set<Integer> set = new HashSet<>(); public MyRunnable() { } public MyRunnable(int start, int end) { this.start = start; this.end = end; } @Override public void run() { for (int i = start; i < end; i++) { set.add(i); } System.out.println(Thread.currentThread().getName() + "添加完毕"); } }

测试代码:

public class Test { public static void main(String[] args) throws InterruptedException { System.out.println("嗨客网(www.haicoder.net)\n"); MyRunnable r1 = new MyRunnable(0,1000); MyRunnable r2 = new MyRunnable(1000,2000); Thread t1 = new Thread(r1,"线程A"); Thread t2 = new Thread(r2,"线程B"); // 线程运行 t1.start(); t2.start(); // 等待线程运行结束 t1.join(); t2.join(); // 打印集合长度 System.out.println("集合长度:" + MyRunnable.set.size()); } }

运行结果如下图:

16 HashSet线程安全.png

以上案例发现最终的集合长度小于 2000 ,得出 HashSet 是线程不安全的,若要解决该问题,应该使用线程安全的 CopyOnWriteArraySet。