2011-03-03 50 views
0

我嘗試處理另一個線程中不同運行的輸出。首先,我將所有可運行的程序添加到一個集合中,並嘗試觸發它們的進度,並將這些進程保存到類別中的映射toether。該類別是每個可運行的標識符。每個類別只能有一個可運行的程序。如何正確處理線程的輸出? java

之後,我嘗試寫出標準輸出上的進度條中的輸出。但每次都是空的(0%)。奇怪的是,當我在Eclipse中調試時,一步一步,進度欄似乎正常工作。我找不到問題,可能是某個時間問題,或其他問題。 有人可以告訴我做錯了什麼嗎?

如果有人知道處理不同線程輸出的更好方法,請告訴我。我很高興,當然。

在此先感謝您的幫助。

這是我WriterThread:

public class WriterT extends Thread { 

Set<Runnable> my_runnables = new HashSet<Runnable>(); 
Map<String, Integer> all_runnable_progress = new HashMap<String, Integer>(); 

public WriterT() { 

} 


public void add(Runnable r) { 
    my_runnables.add(r); 
} 


public void run() { 

    if(!my_runnables.isEmpty()) { 

     int progress = 0; 

     while(true) { 
      for(Runnable r : my_runnables) { 
       if(r instanceof Verify_TestRun) { 
        Verify_TestRun run = (Verify_TestRun)r; 
        progress = run.get_progress(); 
        all_runnable_progress.put(run.get_category(), progress); 
       } 
      } 

      if(progress <= 100) { 
       print_progress(); 
      } else { 
       break; 
      } 

      try { 
       Thread.sleep(150); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 


private void print_progress() { 

    StringBuilder str_builder = new StringBuilder(); 

    for(String cat : all_runnable_progress.keySet()) { 

     int percent = all_runnable_progress.get(cat); 

     str_builder.append(cat + "\t["); 
     for(int i = 0; i < 25; i++){ 
      if(i < (percent/4)){ 
       str_builder.append("="); 
      }else{ 
       str_builder.append(" "); 
      } 
     } 

     str_builder.append("] " + percent + "%" + "\t"); 
    } 

    System.out.print("\r" + str_builder.toString()); 
} 

}

回答

1

後的新信息更新答案

所以,如果我理解正確的話,你想要去在每個測試運行你跟蹤,看看它們中的任何一個是否仍在運行,即進度小於100並且只要它們沒有完成就打印進度。

首先,您需要考慮Stephen C在答案中所說的內容 - 您(可能)想總結每個測試運行的進度值。然後,檢查每次測試的總和是否小於100。如果確實如此,至少有一次測試運行仍在進行中,您將打印進度並保留在循環中。如果你發現你的總和在每次測試中都達到100,那麼你就完成了。您最後一次打印進度以更新輸出以反映100%,然後從循環中斷開。

這裏是我建議的落實,使得小的改動代碼:

public void run() { 
    if(!my_runnables.isEmpty()) { 

     int progress = 0; 

     while(true) { 
      for(Runnable r : my_runnables) { 
       if(r instanceof Verify_TestRun) { 
        Verify_TestRun run = (Verify_TestRun)r; 
        //change #1 - sum up the progress value of each test 
        progress += run.get_progress(); 
        all_runnable_progress.put(run.get_category(), progress); 
       } 
      } 

      //change #2 - break when all done 
      if(progress < (100 * my_runnables.size())) { 
       //check if tests are still running i.e. there are test runs with progress < 100 
       print_progress(); 
      } else { 
       //otherwise print one last status (to update all status' to 100%) before stopping the loop 
       print_progress(); 
       break; 
      } 

      try { 
       Thread.sleep(150); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

不宜progress被內for循環檢查?你現在正在做的是遍歷所有Runnable s並將progress設置爲進度值並將其添加到地圖中。但是,你立即轉移到下一個Runnable。最終的結果是,一旦離開循環,progress的值就是您處理的最後一個Runnable的值。

+0

謝謝你的回答。我想我沒有解釋清楚。每個Verify_TestRun(實現Runnable)都有一個稱爲category的私有字段,因此每個Runnable都具有此類別值,因爲它是標識符。所以在for循環之後,應該有,比如Map 中的3個條目,每個category/Runnable都有一個條目。在for循環之後,我嘗試通過調用print_progress()來打印出當前的值。 – nyyrikki 2011-03-03 16:33:30

+0

@nyyrikki如果這仍然不是你需要的,那麼恐怕你需要進一步澄清你的問題。並且請注意Stephen C關於名稱的建議--Java使用駱駝大小寫的名稱,並提供了何時以大寫字母開頭以及何時以小寫字母開頭的某些建議。你很少會找到用下劃線('_')分隔的單詞,而是用大寫開始下一個單詞的字母。所以'printProgress()'不是'print_progress()'和'allRunnableProgress'而不是'all_runnable_progress'等等。你可以閱讀更多關於[Java代碼約定](http://bit.ly/dOILA3) – 2011-03-03 20:32:00

+0

我以某種方式習慣於這'壞風格',但應該沒有問題來改變這一點。明天我再次處理這個問題。 – nyyrikki 2011-03-03 20:40:36

1

我認爲這可能是問題行:

progress = run.get_progress(); 

鑑於背景下,progress最終會爲最後Verify_RunTest返回的值,但我懷疑你的意思是它是總和的值。

(順便說一句 - Verify_RunTest是不好的風格應該是VerifyRunTest。)

+0

再次感謝您的幫助,我想您昨天也幫了我。請檢查下一個評論。 – nyyrikki 2011-03-03 16:36:58

+0

uiuiui,現在我明白你的意思了。直到現在還沒有看到。但這並不是問題所在,但我必須解決這個問題。 – nyyrikki 2011-03-03 17:46:32