我試圖使用多線程來訪問Hashtable,因爲Hashtable是線程安全的get。但我無法得到它的工作。java多線程訪問Hashtable
我認爲本地計數器的總和應該等於Hashtable或global_counter的大小。但事實並非如此。
多個線程獲取java.util.NoSuchElementException:Hashtable枚舉器錯誤。我認爲這個錯誤是由於枚舉Hashtable造成的。是這樣嗎?
TestMain:
public class TestMain {
// MAIN
public static void main(String argv[]) throws InterruptedException
{
Hashtable<Integer, Integer> id2 = new Hashtable<Integer, Integer>();
for (int i = 0; i < 100000; ++i)
id2.put(i, i+1);
int num_threads = Runtime.getRuntime().availableProcessors() - 1;
ExecutorService ExeSvc = Executors.newFixedThreadPool(num_threads);
for (int i = 0; i < num_threads; ++i)
{
ExeSvc.execute(new CalcLink(id2, i));
}
ExeSvc.shutdown();
ExeSvc.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
CalcLink:
public class CalcLink implements Runnable {
private Hashtable<Integer, Integer> linktable;
private static Enumeration keys;
private static int global_counter;
private int thread_id;
private int total_size;
public CalcLink(Hashtable<Integer, Integer> lt, int id)
{
linktable = lt;
keys = lt.keys();
thread_id = id;
total_size = lt.size();
global_counter = 0;
}
private synchronized void increment()
{
++global_counter;
}
@Override
public void run()
{
int counter = 0;
while (keys.hasMoreElements())
{
++counter;
increment();
Integer key = (Integer)keys.nextElement();
Integer value = linktable.get(key);
}
System.out.println("local counter = " + Integer.toString(counter));
if (thread_id == 1)
System.out.println("global counter = " + Integer.toString(global_counter));
}
}
每個單獨的操作可能是線程安全的,但是,這並不意味着它是線程安全的,做他們一個接一個沒有明確持有鎖。 (此外,'Hashtable'和'Enumeration'已經幾乎在這一點上不建議使用至少15年。) –
不幸的是併發編程是不是可以通過試錯來有效地學習(因爲我發現我自己成本),我肯定會發現,給出了什麼是一個完整的概述一本好書或補習的東西,像Java併發實踐,甚至是官方Java教程。 – biziclop
什麼是使用多線程讀取Hashtable或HashMap中元素的最佳/更好的方法? – stevenhz