2015-12-10 60 views
8

该程序后9个打印完成:如何停止ScheduledExecutorService?

class BeeperControl { 

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 

    public void beep() { 
     final Runnable beeper = new Runnable() { 
      public void run() { 
       System.out.println("beep"); 
      } 
     }; 
     final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
       beeper, 1, 1, SECONDS); 
     scheduler.schedule(new Runnable() { 
      public void run() { 
       beeperHandle.cancel(true); 
      } 
     }, 1 * 9, SECONDS); 
    } 

    public static void main(String[] args) { 
     BeeperControl bc = new BeeperControl(); 
     bc.beep(); 
    } 
} 

如何停止的处理(在蚀例如即java程序),因为它不会在第9秒的时间限制之后停止?

+0

那么......你是什么意思“它在9秒内没有停止时间限制”?我只是测试了它,9秒后“哔哔”停止了,如预期的那样。当然,整个程序并没有停止,因为你没有关闭线程池。如果 - 而不是取消蜂鸣器 - 只需在9秒钟后关闭调度程序,程序也将正常退出。这是你想要的行为吗? – Seelenvirtuose

回答

11

您遇到的问题是调度程序在取消嘟嘟声任务后保持活动线程。

如果存在活动的非守护线程,则JVM保持活动状态。

,它不断围绕这个主题的原因是,你告诉它在这一行这么做:

private final ScheduledExecutorService scheduler 
     = Executors.newScheduledThreadPool(1); 

newScheduledThreadPool(int corePoolSize)文档:

corePoolSize - 线程数留在游泳池里,即使他们闲着。

所以,你有两种可能的方式来使JVM终止:

  1. 通行证0newScheduledThreadPool而不是1调度不会保持活动线程,而JVM将终止。

  2. 关闭调度程序。无论如何,你应该这样做来释放它的资源。因此,改变run在您的匿名Runnable到:

    public void run() { 
        beeperHandle.cancel(true); 
        scheduler.shutdown(); 
    } 
    

(其实你不需要cancel那里 - 在shutdown将尽快为下一个“嘟”完成后生效。)

+0

您是否注意到线程正在运行旧代码并且即使在服务器重新启动并且apache和tomcat已被关闭并保留之后也无法关闭的问题。 我有一个电子邮件runnable,这是在错误的时间发送,我改变了电子邮件的内容和时间,现在2个电子邮件正在发送,尽管更改我的代码(我的代码上contextIntialized只创建一个可运行,所以我怀疑以某种方式旧的runnable没有被正确的杀死,因为我忘了在旧版本的代码中添加关闭代码) 您的建议将会有所帮助:D –