2015-11-04 46 views
1

我有2个代码片段,一个使用ScheduledExecutorService在特定时间执行一个线程,另一个使用Timer在特定时间执行TimerTask。问题是使用ScheduledExecutorService时,即使线程的run()达到最后,监视器程序仍然指示它仍然存在(参见下图)。另一方面,TimerTask在执行完成后结束其线程。ScheduledExecutorService不会像Timer一样结束线程

我已将ScheduledExecutorService的Thread更改为TimerTask,但收到相同的结果。如何在使用ScheduledExecutorService时解决问题?

计时器:

TimerTask task = new TimerTask() 
    { 
     @Override 
     public void run() 
     { 
      System.out.println("doing something"); 
     } 
    }; 

    Timer t = new Timer(); 
    t.schedule(task, 250); 

Thread count while using Timer

ScheduledExecutorService的:

Thread task = new Thread() 
    { 
     @Override 
     public void run() 
     {    
      System.out.println("doing something"); 
     } 
    }; 

    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 
    scheduler.schedule(task, 250, TimeUnit.MILLISECONDS); 

Thread count while using ScheduledExecutorService

+0

您不提交线程到执行程序服务,您提交runnables。 –

回答

2

在您的第二个片段中,您创建了Thread实例,但ScheduledExecutorService已将该实例用作Runnable,即。它只关心其run方法。它实际上并不是startThread

ScheduledExecutorService维护自己的Thread(s)执行任务。与​​,这是一个单一的非守护进程Thread。您需要shutdownScheduledExecutorService才能完成该Thread

javadoc of Timer状态

后的最后一次现场参照Timer对象消失,所有 未完成的任务已完成执行,计时器的任务执行 线程终止优雅(并成为受垃圾 集合) 。

执行完TimerTask后,它将完成其内部线程。

+0

我将'scheduler.shutdown()'添加到'run()'的末尾,并且它工作正常。然而,我使用Thread的原因是实现'thread.setUncaughtExceptionHandler(uncaughtExceptionHandler)',因为'ScheduledExecutorService'使用它自己的线程,'setUncaughtExceptionHandler'因此没有效果?无论如何,我可以访问ScheduledExecutorService的Thread并设置它的'UncaughtExceptionHandler'? – user945711

+0

@ user945711那不行。一个'Thread'的'uncaughtExceptionHandler'实际上只被为该'Thread'对象创建的线程使用。 –

+0

@ user945711'schedule'给你一个'Future'。你可以在那里处理你的例外。 –

相关问题