【发布时间】:2018-09-05 11:58:10
【问题描述】:
我知道HashMap不保证顺序。考虑以下代码:
import java.util.HashMap;
import java.util.Map;
public class SandBox {
protected static class Book {
String name;
public Book(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
protected static class MyThread extends Thread {
@Override
public void run() {
super.run();
final int n = 10;
Book[] books = new Book[n];
for (int i=0; i<n; i++)
books[i] = new Book("b" + i);
for (Book b : books)
System.out.print(b + ", ");
System.out.println();
HashMap<Book, Object> hm = new HashMap<>();
for (Book b : books)
hm.put(b, null);
for (Map.Entry<Book, Object> entry : hm.entrySet())
System.out.print(entry.getKey() + ", ");
System.out.println();
}
}
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
t.join();
}
}
在每次运行中,HashMap 的顺序是不同的(如预期的那样)。例如:
输出 #1:
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9,
b3, b4, b7, b9, b0, b8, b1, b2, b6, b5,
输出#2:
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9,
b9, b4, b3, b7, b8, b0, b1, b5, b6, b2,
但奇怪的是,如果我替换这些行
t.start();
t.join();
与
t.run();
(不使用多线程)输出总是一样的:
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9,
b0, b3, b7, b4, b2, b6, b9, b1, b5, b8,
我不明白 HashMap 的 order 和 Thread 的关系。有人可以向我解释为什么会这样吗?
【问题讨论】:
-
@ChristopheRoussy 我不认为它是重复的;但它是相关的。
-
您可以通过将 toString 更改为
return name + " " + hashCode() % 10_000;来使输出更有趣(使用模块使输出适合屏幕) - 您可以看到 hashCode 在单线程之间没有变化运行,它在一个线程中运行。至于为什么? shrug 使用单个线程更具确定性。但无论如何你都不应该依赖它。
标签: java multithreading hashmap