[英]Updating (and Iterating) a Map in Java
我已經在Java 7食譜書中看到了以下代碼,可以同時更新和迭代Map:
ConcurrentMap<Integer,String> concurrentMap = new ConcurrentHashMap<Integer, String>();
for (int i =0;i < 1000;i++) {
startUpdateThread(i, concurrentMap);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (Map.Entry<Integer, String> entry : concurrentMap.entrySet()) {
System.out.println("Key :"+entry.getKey()+" Value:"+entry.getValue());
}
並且更新地圖的方法如下:
private void startUpdateThread(int i, final ConcurrentMap<Integer, String> concurrentMap) {
Thread thread = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
int randomInt = random.nextInt(20);
concurrentMap.put(randomInt, UUID.randomUUID().toString());
}
} });
thread.setName("Update Thread "+i);
updateThreads.add(thread);
thread.start();
}
我只嘗試使用HashMap代替ConcurrentHasMap,結果是相同的(使用Java VisualVM監視)。 有人知道為什么嗎?
謝謝,奧古斯丁
更新:一些有趣的問題:
ConcurrentHashMap
允許多線程訪問,而HashMap
則不允許。
同時從多個線程調用HashMap#put
可能會破壞您的地圖。 ConcurrentHashMap
處理這些情況並緩解競爭狀況。
特別是對於您的測試,您的地圖只有20個鍵,這意味着它將相對較快地充滿。 哈希圖的弱點是當您需要擴展存儲桶空間並同時放置另一個條目時。 嘗試增加Integer.MAX_VALUE
的鍵數量,您將有更大的機會看到它被破壞。
下面的代碼將為您提供不同的結果。 您的代碼不會崩潰的原因是一個很小的20個整數的隨機間隔。 因此,您的地圖會立即變滿,並且此后它的密鑰集不會被修改。 我將隨機間隔更改為10000並添加了睡眠,因此現在它在程序運行期間不斷更新,並導致HashMap
崩潰。 它適用於ConcurrentHashMap
,它能夠遍歷正在修改的數據。
public class Test {
static List<Thread> threadList = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
Map<Integer,String> map = new HashMap<>();
for (int i =0;i < 1000;i++) {
startUpdateThread(i, map);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println("Key :"+entry.getKey()+" Value:"+entry.getValue());
}
for (Thread thread : threadList) {
thread.interrupt();
}
}
private static void startUpdateThread(int i, final Map<Integer, String> concurrentMap) {
Thread thread = new Thread(new Runnable() {
public void run() {
Random random = new Random();
while (true) {
int randomInt = random.nextInt(10000);
concurrentMap.put(randomInt, UUID.randomUUID().toString());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
}
} });
threadList.add(thread);
thread.setName("Update Thread " + i);
thread.start();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.