2016-08-03 59 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