2012-01-09 276 views
19

我注意到NetBeans警告我在我的Java代碼的while循環中使用Thread.sleep(),所以我對這個主題做了一些研究。看起來問題主要是表現問題,在計數器仍然處於睡眠狀態時,您的條件可能會變爲真,因此在等待下一次迭代時會浪費時間。這一切都非常有意義。while while循環中的Thread.sleep()

我的應用程序需要聯繫遠程系統並定期輪詢操作的狀態,等到操作完成後再發送下一個請求。目前的代碼邏輯做到這一點:

String state = get state via RPC call 
while (!state.equals("complete")) { 
    Thread.sleep(10000); // Wait 10 seconds 
    state = {update state via RPC call} 
} 

鑑於該情況是檢查的遠程操作(這是一個昂貴的過程,因爲它運行幾秒鐘),這是一個有效的線程使用。 sleep()在一個while循環?有沒有更好的方法來構造這種邏輯?我已經看到了一些我可以使用Timer類的例子,但是我沒有看到好處,因爲它似乎仍然歸結爲上面相同的簡單邏輯,但是引入了更多的複雜性。

Bear記住,在這種情況下,遠程系統既不在我的直接控制之下,也不在Java中編寫,所以在這種情況下將此端改爲「合作」不是一種選擇。我更新我的應用程序狀態值的唯一選擇是創建和發送XML消息,接收響應,解析它,然後提取我需要的信息。

任何建議或意見將是最受歡迎的。

+0

我想在你的情況是完全正確的(如果你不能得到通知,當RPC調用完成)。解決警告的方法是在週期中使用do。 – kenota 2012-01-09 17:51:04

+2

我認爲輪詢RPC調用狀態的成本需要相當高才能保證10秒鐘的睡眠。一秒鐘更合理,或根據先前的睡眠操作次數等待更長時間的睡眠(當然有一定的最大值)。 – 2012-01-09 19:48:28

+1

正如我所說的,遠程操作運行幾秒鐘(我的意思是從3-5的任何地方)。鑑於一些邊緣情況,有一種情況是10秒太短。 – 2012-01-10 12:57:25

回答

12

除非您的遠程系統能夠發出事件或以其他方式異步通知您,否則我認爲上述內容完全不合理。您需要平衡您的sleep()時間與RPC調用的時間/負載之間的平衡,但我認爲這是唯一的問題,並且上述內容似乎完全不受關注。

4

不能改變遠端來提供一個「推送」通知,說明它是在其長時間運行的過程中完成的,這與你將能夠做到的一樣。只要Thread.sleep時間與輪詢成本相比較長,您應該可以。

0

你應該(幾乎)從不使用睡眠,因爲它非常低效,而且它不是一個好習慣。總是使用線程互相發信號的鎖和條件變量。見麥克道林的Coding Standards for Programming with threads

模板是:

public class Foo{ 
    private Lock lock; 
    private Condition c1; 
    private Condition c2; 

    public Foo() 
    { 
    lock = new SimpleLock(); 
    c1 = lock.newCondition(); 
    c2 = lock.newCondition(); 
    ... 
    } 

    public void doIt() 
    { 
    try{ 
     lock.lock(); 
     ... 
     while(...){ 
     c1.awaitUninterruptibly(); 
     } 
     ... 
     c2.signal(); 
    } 
    finally{ 
     lock.unlock(); 
    } 
    } 
} 
+3

我不太清楚這應該如何幫助。 – 2012-01-09 21:12:48

+0

嗯,我想他是問如何構建他的邏輯,我說(作爲一般性評論),在while循環中,他應該使用一個條件變量來表示正在等待完成的過程,而不是連續使用睡覺。 – Cemre 2012-01-09 21:22:48

+2

我認爲這忽略了RPC需要以某種方式進行輪詢的實際問題,不是嗎? – 2012-01-09 21:31:19