Khi chạy lớp sau ExecutionService thường sẽ bế tắc.Tại sao ExecutorService bế tắc khi thực hiện các thao tác HashMap?
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTest {
public static void main(final String[] args) throws InterruptedException {
final ExecutorService executor = Executors.newFixedThreadPool(10);
final HashMap<Object, Object> map = new HashMap<Object, Object>();
final Collection<Callable<Object>> actions = new ArrayList<Callable<Object>>();
int i = 0;
while (i++ < 1000) {
final Object o = new Object();
actions.add(new Callable<Object>() {
public Object call() throws Exception {
map.put(o, o);
return null;
}
});
actions.add(new Callable<Object>() {
public Object call() throws Exception {
map.put(new Object(), o);
return null;
}
});
actions.add(new Callable<Object>() {
public Object call() throws Exception {
for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
iterator.next();
}
return null;
}
});
}
executor.invokeAll(actions);
System.exit(0);
}
}
Vậy tại sao điều này lại xảy ra? Hoặc tốt hơn - làm thế nào tôi có thể viết một bài kiểm tra để đảm bảo rằng việc triển khai bản đồ trừu tượng tùy chỉnh là luồng an toàn? (Một số triển khai có nhiều bản đồ, một đại biểu khác thực hiện bộ nhớ cache, v.v.)
Một số nền: điều này xảy ra trong Java 1.6.0_04 và 1.6.0_07 trên Windows. Tôi biết rằng vấn đề xuất phát từ sun.misc.Unsafe.park():
- tôi có thể tạo lại vấn đề trên máy tính xách tay Core2 Duo 2.4Ghz của tôi, nhưng không phải trong khi đang chạy trong debug
- Tôi có thể gỡ lỗi trên Core2 của tôi Quad tại nơi làm việc, nhưng tôi đã treo nó qua RDP, như vậy sẽ không thể có được một chồng dấu vết đến ngày mai
Hầu hết các câu trả lời dưới đây là về sự an toàn phi chủ đề của HashMap, nhưng tôi có thể tìm không có chủ đề bị khóa trong HashMap - nó là tất cả trong mã ExecutionService (và Unsafe.park()). Tôi sẽ kiểm tra chặt chẽ các chủ đề vào ngày mai.
Tất cả điều này vì triển khai Bản đồ trừu tượng tùy chỉnh không an toàn chỉ vì vậy tôi đặt đảm bảo rằng tất cả các triển khai sẽ an toàn chỉ. Về bản chất, tôi muốn đảm bảo rằng sự hiểu biết của tôi về ConcurrentHashMap vv là chính xác những gì tôi mong đợi, nhưng đã tìm thấy ExecutionService để được kỳ lạ thiếu ...
hành động hiện tại của tôi cho ngày mai: 1. Kiểm tra chặt chẽ để đề dừng lại ở HashMap [resize] code 2. Nâng cấp lên vm mới nhất – Stephen
Bạn sẽ không nhận được bất kỳ đề dừng lại thay đổi kích thước - họ sẽ thay đổi kích thước và thoát. Kiểm tra thread bị mắc kẹt trong đó iterating iterable Callable. –