2012-07-11 82 views
1

这是我的一段代码:如何打破无限循环

// TODO Auto-generated method stub 
     try 
     { 
      Socket clientSocket = new Socket("localhost", 8888); 

      ObjectOutputStream ous = new ObjectOutputStream(clientSocket.getOutputStream()); 

      while(sending) 
      { 
       Statistics statsData = setStatisticsData(); 
       ous.writeObject(statsData); 

       Thread.sleep(5000); 
      }   
     } 
     catch(UnknownHostException uhe) 
     { 
      uhe.printStackTrace(); 
     } 
     catch(IOException ioe) 
     { 
      ioe.printStackTrace(); 
     } 
     catch (InterruptedException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

它的client.it'll无限循环发送对象统计。我会实现一种方法来通过输入来打破这个无限循环(例如,按下键盘上的按钮).ok我可以做什么?我怎样才能打破无限循环?

回答

4

如果这是一个单独的线程:

Thread statisticsSendingThread = ... 

然后简单中断它:

statisticsSendingThread.interrupt(); 

InterruptedException将被抛出,从环路逃逸。

我看到你已经有了一个布尔值sending的标志。它也会起作用,但在最坏的情况下会延迟5秒钟。还要确保它是volatile - 或更好的,使用isInterrupted()线程的方法。但使用interrupt()中断线程是迄今为止最简单的方法(不需要额外的编码)。你的循环可以是真正无限的(while(true)虽然有while(!isInterrupted()))。


顺便说一句,你的setStatisticsData()应该叫getStatisticsData()

+0

使用interrupt()的另一个好处是它会中断sleep,wait等各种高级阻塞调用。你无法用自定义的“我们已被杀死”的标志实现这一点 – 2012-07-11 13:21:09

+0

@Tomasz Nurkiewicz但我应该在哪里打断线程? – user1508419 2012-07-11 13:21:36

+0

@ user1508419 - 在任何线程从键盘读取按键事件或字符。 – 2012-07-11 13:23:28

0

你必须在单独的线程上完成它们,因为你正在寻找用户输入,所以最好将你的代码移动到某个异步线程,然后简单地通过输入将你的sending bool设置为false或者中断线程YourThread.interrupt();

-1
while(sending) 
{ 
    Statistics statsData = setStatisticsData(); 
    ous.writeObject(statsData); 
    Thread.sleep(5000); 
    if(EXIT_FLAG == true) 
     sending = false; 
}  

EXIT_FLAG可以是一个静态变量,可以从外部更新。您可能还想在单独的线程中运行此无限循环。详细了解如何在线程之间共享数据。

+0

'if(EXIT_FLAG)break;'?你为什么用大写字母命名变量?不是我倒下了。 – 2012-07-11 13:13:09

+0

“您可能还想在单独的线程中运行此无限循环。”如果不在单独的线程上,EXIT_FLAG将如何设置? – NominSim 2012-07-11 13:14:03

+0

@TomaszNurkiewicz - 为了更好的可读性。为什么Calendar.DAY_OF_YEAR是大写字母?我不知道为什么倒票。但是打断一个线程并不是解决这个问题的方法。有一个干净的方式来摆脱循环。 – sreehari 2012-07-11 13:17:22