2012-07-24 39 views
0

我有一個有三個線程和一個存儲數據的散列圖的類。其中一個線程將數據寫入hashmap,另外兩個線程讀取數據。事情是這樣的:在java中通過3個線程訪問變量

public static class collector{ 
    Thread writter; 
    Thread reader1; 
    Thread reader2; 
    HashMap storage; 
    ... 
    public void write(String s){ 
    storage.put(s.hashcode(),s); 
    } 
    public String read(long hash){ 
    return storage.get(hash); 
    } 
    public Set readAll(){ 
    return storage.entrySet(); 
    } 
} 

我想第一個線程(作家)運行第一種方法(寫)和reader1運行閱讀和閱讀器2運行readAll。但我無法找到線程訪問存儲(運行方法)。我如何編寫線程來像這3種方法一樣運行,同時他們都可以同時訪問存儲?

回答

1

由於類是靜態的,你可以簡單地調用從線程的run方法collector.write。

+0

謝謝。你救了一條命;) – Alireza 2012-07-25 00:23:34

+0

這個答案是不正確的。看看Java文檔中關於「靜態」類的實際意義 - 它與「靜態」變量或「靜態」方法無關,這就是您正在考慮的內容。 – 2012-07-25 04:07:16

+0

無論如何,這工作 – Alireza 2012-07-25 12:41:35

0

使用該變量編寫單例類,並寫入,讀取,讀取所有方法。看到您在storage對象上同步或同步這些方法。從三個線程訪問這個單例類。

2

首先,爲了使這個類是線程安全的,您應該使用線程安全的哈希映射實現,如java.util.concurrent.ConcurrentHashMap而不是普通的舊的java.util.HashMap

另一張海報建議在一個單例中保存一個collector實例,這相當於一個全局變量。我不會使用全局數據,而是將collector實例傳遞給每個線程。您可以定義Runnable的子類,該子類將collector實例作爲其構造函數的參數。將collector存儲在實例變量中。然後從run()方法中使用它。當你開始你的線程時,給每個對象一個不同的Runnable對象(使用合適的Thread構造函數)。

喜歡的東西:

class MyTask implements Runnable { 
    private collector myCollector; 
    public MyTask(collector _myCollector) { 
    myCollector = _myCollector; 
    } 
    public void run() { 
    // do something with myCollector 
    } 
} 
+0

它並不需要安全。因爲他們中的一個只是寫入散列表。另外兩個閱讀它。我的問題是,當我想在'collector'類中定義一個線程('implements runnable')時,我無法訪問'storage'。我怎樣才能訪問'存儲'hashmap。 – Alireza 2012-07-24 23:21:24

+0

對不起,我沒有看到你編輯。 如何定義一個實例變量? – Alireza 2012-07-24 23:25:15

+1

是的,它需要是線程安全的。相信我。如果你沒有使它成爲線程安全的,它可能在大多數情況下工作,但有時它可能會失敗。 (例如,將數據添加到「HashMap」中時,可能需要擴展Map內部使用的存儲空間。如果讀取器在擴展時試圖遍歷該結構,則可能會得到'NullPointerException'或類似的東西。) – 2012-07-24 23:25:29