2012-07-11 118 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