【发布时间】:2018-02-24 00:06:54
【问题描述】:
===更新====
来自评论
所以我清楚地阅读了文档并且知道它不是线程安全的,我想运行一个小实验来看看它会如何中断。所以文档说结果是不确定的。有谁知道会发生什么?如果我想证明它不是线程安全的,我该如何编写示例代码才能真正看到它不是线程安全的?你们是否真的尝试过并看到不起作用的例子?你有示例代码吗?
如果我有三个线程访问字符串的哈希集。
- 添加新字符串
- 第二次删除字符串
- 第三次全部删除
HashSet 线程安全吗?
public void test()
{
Set<String> test = new HashSet<>();
Thread t0= new Thread(new Runnable() {
@Override
public void run() {
while (true) {
boolean c = test.contains("test");
System.out.println("checking " + c);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
test.add("test");
System.out.println("adding");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (!test.isEmpty())
{
test.removeAll(test);
}
System.out.println("removing");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t0.start();
t1.start();
t2.start();
while(true) {
}
}
我有这个测试代码并运行它,它似乎工作。没有抛出异常。我有点困惑,因为 HashSet 不是线程安全的。 我怎么不见了?
【问题讨论】:
-
不,不是。您是否费心阅读文档,即
HashSet的javadoc?它是这样说的:注意这个实现是不同步的。如果多个线程同时访问一个哈希集,并且至少有一个线程修改了这个集,那么它必须是同步的外部。 -
我读过。这就是为什么我说它令人困惑。如果你运行代码,它不会破坏任何东西。
-
为什么期望抛出异常?哪些例外?
-
我没有看到任何关于 javadoc 所说的内容令人困惑的地方。请解释为什么您认为它令人困惑。否则,基本上,您的问题没有什么可回答的。除了一个字:没有。
-
所以我清楚地阅读了文档并且知道它不是线程安全的,我想运行一个小实验来看看它会如何破坏。所以文档说结果是不确定的。有谁知道会发生什么?如果我想证明它不是线程,我如何编写示例代码以便我可以真正看到它不是线程安全的?你们是否真的尝试过并看到这个不起作用的例子?有示例代码吗?
标签: java multithreading concurrency thread-safety hashset