2016-08-03 13 views
1

我已經設置了一個JavaThread類,它執行一個特定的任務,創建一個新的Process並與其他各種東西一起運行。Java線程:使用run()中的interrupt()是否可以在完成其任務時停止線程?

在其調用Thread父類的我已經建立了循環

while(!thread.isActive()) { 
... 
} 

我想知道這是否是最好的做法/接受更新run()Thread類發出interrupt()

run() { 
    callTask(); 
    interrupt(); 
} 

更新

然後我可以在Thread創建booleanfinished場,並更改爲true一旦callTask​​()完成,並有家長找

主題:

run() { 
    callTask(); 
    finished = true; 
} 

家長:

// Start the threads for each Device 
     for (DeviceRunner deviceRunner : deviceRunners) { 
      deviceRunner.start(); 
     } 

     boolean doneProcessingDevices = false; 
     while (!doneProcessingDevices) { 
      Set<DeviceRunner> deviceRunnersToRemove = new HashSet<DeviceRunner>(); 
      for (DeviceRunner deviceRunner : deviceRunners) { 
       if (deviceRunner.isFinishedRunning()) { // check to see if the thread is finished 
        deviceRunnersToRemove.add(deviceRunner); 
       } 
      } 

      // remove the device runners which are no longer active 
      deviceRunners.removeAll(deviceRunnersToRemove); 

      if (deviceRunners.isEmpty()) { 
       doneProcessingDevices = true; 
      } 

      Thread.sleep(1000); 
     } 

謝謝

+0

你想讓線程「中斷」它對應的'Thread'對象,基本上會中斷它自己嗎? –

+1

你想讓一個線程自行中斷嗎?那是什麼意思? 't.interrupt()'的目的是獲得線程't'來關注一些已經改變的重要事情(通常是「關閉」請求)。你的線程不需要引起注意。它已經有了自己的關注。 –

+0

@SotiriosDelimanolis我只是設置了中斷,以便父線程知道線程何時完成。我注意到,即使線程在run()中不再有任何任務要執行,thread.isActive在某些情況下也會不斷返回true。 我應該只是在線程中放入一個布爾值,然後更改它,並且在線程完成時讓父級外觀爲它設置? – ALM

回答

1

只是爲了澄清暫停執行:您不必手動停止線程。當run()完成時,本地線程將死亡並且Thread對象將被垃圾收集。

如果您希望父母等待所有任務完成,則可以使用CountDownLatch。用必須完成的任務數來初始化鎖存器。每次任務完成後,讓他調用countDown()。在此期間,上await()父塊:

造成當前線程在等待,直到鎖存器倒計數至零,除非線程被interrupted

這MWE演示了基本思路:

int numberOfTasks = 3; 
CountDownLatch latch = new CountDownLatch(numberOfTasks); 

while (numberOfTasks-- > 0) { 
    new Thread(() -> { 
     try { 
      // Do stuff. 
      System.out.println("Done."); 
     } finally { 
      latch.countDown(); 
     } 
    }).start(); 
} 

try { 
    latch.await(); 
    System.out.println("All tasks finished."); 
} catch (InterruptedException e) { /* NOP */ } 

你不會看到All tasks finished.每個任務都有打印Done.之前。

+0

我想我遇到了一個讓我相信我需要真正結束這個線程的錯誤,因爲它不斷地被設置爲活着。事實證明,這個bug導致'task'的某個部分保持打開狀態,永遠不會結束,這意味着線程永遠不會結束run()。 感謝您的詳細信息,我會看看是否應該考慮使用此方法。 – ALM

0

我相信你真正想要的是Thread.join方法。從Oracle tutorial複製

join方法允許一個線程等待另一個線程的完成。如果T是一個Thread對象,它的線程當前執行,t.join() 導致當前線程,直到T的線程終止

+0

我不知道什麼時候線程從父節點完成。我只知道線程在線程類內完成的時間。 – ALM

+0

你不需要知道這一點。你只需調用'join',這會阻塞你的線程(正在調用'join'的線程)直到另一個線程完成。 – Nikem

+0

檢查上面。我正在運行多個線程,每個線程都有相同的任務完成,當他們完成時,我想刪除它們並完成。從內部殺死線程的最佳做法是什麼? JOIN(): 等待最多毫秒毫秒爲此線程死亡。超時時間爲0意味着永遠等待。 該實現使用this.wait調用的一個循環調用this.isAlive。當一個線程終止this.notifyAll方法被調用。建議應用程序不要在Thread實例上使用wait,notify或notifyAll。 – ALM

相關問題