2016-08-12 28 views
1

現在我有兩個線程在我的程序中運行。一個人不斷嘗試讀取用戶的輸入,另一個人觀看超時。如果用戶在給定的時間內沒有發送任何輸入,則會發生超時。這兩個線程是這樣的:我應該有專門的線程來觀看超時嗎?

用戶輸入線程

while(true){ 
    if(in.hasNextLine()){ 
     processLine(in.nextLine()); 
     timeLastRecieved = System.currentTimeMillis(); 
    } 
} 

超時線程

while(true){ 
    //Check for a timout 
    if(timeLastRecieved+timeoutDuration <= System.currentTimeMillis()) 
     timeUserOut(); 

    else{ 
     //Sleep until it is possible for a timeout to occur 
     Thread.sleep((timeLastSent+timeoutDuration) - System.currentTimeMillis()); 
    } 
} 

截至目前我有這些線程分開了,但我可以這樣結合他們...

while(true){ 
    if(in.hasNextLine()){ 
     processLine(in.nextLine()); 
     timeLastRecieved = System.currentTimeMillis(); 
    } 

    //Check for a timout 
    if(timeLastRecieved+timeoutDuration <= System.currentTimeMillis()) 
     timeUserOut(); 
} 

但我真的不需要經常檢查超時。所以我應該組合線程並且經常檢查超時,或者我應該有兩個線程。我並不擔心表演,因爲我是正確的編碼禮儀。如果這意味着超過15分鐘的超時時間。

編輯:只想指出,在我睡覺的兩個線程的版本,但在組合版本,我從來沒有睡覺的線程。這顯然會導致檢查超時運行的if語句更加必要。

+0

如果讀線程無論如何都輪詢用戶輸入,它也可以處理超時。畢竟,如果我正確地理解了你,這是等待輸入的超時,因此消費者線程(輪詢)將是超時的。我認爲有一個單獨的線程檢查超時的唯一原因是,如果用戶輸入的處理時間過長,並且例如下一次輪詢將在16分鐘後發生並且用戶在15之後提供輸入: 30兩個輪詢線程都可能無法識別超時。 – Thomas

+0

此外,在處理輸入之前,您可能會考慮放置'timeLastRecieved = System.currentTimeMillis();否則處理所需的時間會增加超時的閾值 - 您可能會也可能不希望發生這種情況。 – Thomas

+0

好點@Thomas。我不必擔心處理的長度,因爲它不應該超過幾毫秒,而超時設置爲大約15分鐘。我的問題的根源在於是否最好有兩個高效的線程,或者一個線程更頻繁地執行if語句,然後是必要的。 – user6629259

回答

0

總結我的意見的通用選項:我不認爲一個單獨的線程來檢查超時是必要的。

原因:

  • 你需要像timeLastRecieved他們之間,這可能比希望更復雜的共享信息(例如,據我所知在某些情況下獲得long值不是原子)。
  • 從您的描述看來,輪詢用戶輸入和超時(沒有提供及時輸入)密切相關,因此輪詢線程也可以檢查超時。這並不意味着它也必須處理超時,只是在某處報告它或調用某個超時處理程序可能是更好的設計。
  • 自更新timeLastRecieved以來,更容易閱讀和理解,並且檢查超時是否在同一地點處理。
  • 由於沒有線程間通信和協調需要(沒有需要通信的線程),它也可能更健壯。

上檢查超時一些提示:

  • 您應該計算超時臨界值,當你更新timeLastReceived然後只檢查agains當前的時間,而不是在每次迭代計算它的。
  • 您可能需要在處理輸入之前計算超時閾值,以避免它也取決於處理時間。

最後,還有其他方法,如使用java.util.Timer。在這裏,您可以簡單地安排一個超時應該發生時執行的超時任務。那麼這個任務將檢查超時是否真的發生,如果不是,它只是返回。

爲了處理新的輸入之前發生超時,你可以使用至少兩種方法:

  • 取消當前的超時任務,從定時器中取出,並安排一個新的。
  • 如果已經有一個預定的超時任務,那麼不要安排一個新的任務,而是等待當前的任務運行。然後當前的人檢查超時,如果沒有發生,它爲當前預期的超時安排一個新的任務(或自己)(注意這需要一些線程間的通信,所以在這裏要小心)。
0

您需要有兩個線程 - 一個等待通過InputStream/Reader進入的數據,另一個正在監視時間以查看時間是否耗費時間太長。使用1個線程的唯一方法是在超時時間段內休眠,然後定期輪詢數據。但是,這不如有一個專門從您的InputStream/Reader讀取的單獨線程。

你可能想看看Timeout作爲執行超時

相關問題