2011-03-03 59 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