2014-10-01 23 views
0

我在java中,我有一個HashMap<String, Deque<Integer>> info;同步一組線程

我的數據進行了走訪與一個小時的時間,維基百科頁面的列表,用多少次的計數一起編寫一個程序的每個都被訪問過。

de Florian_David_Fitz 18 
de G%C3%BCnther_Jauch 1 
de Gangs_of_New_York 2 
de Georg_VI._(Vereinigtes_K%C3%B6nigreich) 7 
de Gerry_Rafferty 2 

該數據會從上面的頁面名作爲關鍵字存儲在HashMapDeque與訪問該小時數每小時更新一次。

我想要有一個線程ThreadRead,它讀取輸入文件並將信息存儲在HashMap中。然後一個ThreadCompute線程爲HashMap中的每個密鑰消耗關聯的Deque

ThreadRead需要鎖定所有ThreadComputes,同時處於激活狀態,然後在完成後將其喚醒,以便ThreadComputes可以同時工作。

如果我需要爲每個ThreadCompute使用不同的互斥鎖,那麼我怎樣才能讓所有鎖定在ThreadRead之間?完成後我怎樣才能從ThreadRead中喚醒所有的ThreadComputes

我已經使用info作爲鎖ThreadReadinfo.get(key)每個ThreadCompute但它沒有按預期工作。

編輯:

我添加了一些代碼,試圖使問題更清楚。這是我目前所擁有的:

HashMap<String, Deque<Integer>> info; 
boolean controlCompute, control Read; 


private static class ThreadRead extends Thread { 

    public void run() { 
     while(controlRead) { 
      try { 
       read(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void read() throws InterruptedException{ 
     synchronized(info){ 
      while(count==numThreads){ 
       for (File file: files){ 
        reader.parse(file, info); // Reads the file and store the data in the Hashmap 
        keys=true; 
        while(info.getSizeDeque()>10){ 
         count=0; 
         info.wait(); 
         info.notifyAll(); 
        } 
       } 
      } 
      controlRead=false; 
     } 
    } 
} 


private static class ThreadCompute extends Thread { 

    public String key; 

    public void run() { 
     while(controlCompute) { 
      try { 
       compute(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void compute() throws InterruptedException{ 
     synchronized(info.get(key)){ 
      if(count!=numThreads){ 
       algorithms(); //Here I apply the algorithms to the integers in the deque 
       if(controlRead){ 
        info.get(key).removeFirst(); 
        count++; 
        if(count==numThreads){ 
         info.notify(); 
         info.get(key).wait(); 
        } 
        info.get(key).wait(); 
       } 
       if(info.isEmptyDeque(key)){ 
        controlCompute=false; 
       } 
      } 
     } 
    } 
} 
+1

我認爲最簡單的(低級別)方法是使用'Object'作爲鎖和'wait' /'notifyAll'機制。但是有很多更高層次的方法可以做到這一點。你應該發佈一些代碼。 – Mena 2014-10-01 16:26:03

+1

是的,如果您發佈所需的最少代碼來重現此問題,則您更有可能獲得更具體的幫助。 [這個問題](http://stackoverflow.com/questions/10946565/java-thread-synchronization-thread-sleep-method-not-working-as-desired)是一個很好的例子。 – 2014-10-01 16:30:38

+0

時間到了。投票結束... – Mena 2014-10-01 16:37:59

回答

2

java.util.concurrent.locks.ReentrantReadWriteLock類對這類問題很好。應該有一個實例來保護整個HashMap。文件讀取器需要獲取編寫鎖的ReadWriteLock,因爲它想修改映射。其他線程需要各自獲取自己的讀取鎖定從一個ReadWriteLock

所有的線程都必須小心儘量限制他們鎖定的範圍,因此,特別是文件讀取線程應該在修改地圖之前立即獲取寫入鎖定,將其保留直到所有修改對於一個條目完成,然後釋放它。其他線程不會彼此阻塞,所以他們原則上可以鎖定更長的鎖,但這樣做會阻止文件讀取器。