2012-12-17 46 views
0

我使用的是ExecutorService用于如下连接任务:shutdownNow时与执行服务

ExecutorService executor = Executors.newSingleThreadExecutor(); 
    Future<ApplicationConnection> future = (Future<ApplicationConnection>) executor.submit(new ConnectThread(crf, connoptions)); 
    connection = future.get(300000, TimeUnit.SECONDS); 
    executor.shutdownNow(); 

()的调用方法调用.connect()方法(专有API)。这种连接方法会产生各种线程池等。我担心的是,如果将来超时并杀死执行程序,将来可能通过调用.connect()方法产生的线程也会结束吗?我知道杀死一个线程也会杀死任何子线程,但这是否遵循相同的逻辑?

回答

2

你是对的,如果Future超时,一些悬挂的线程将保留。更糟糕的是,shutdownNow()甚至不会关闭您的池线程(更不用说私有API线程)。它只是停止接受新的工作。 ExecutorService一旦所有正在运行的任务完成,线程池将终止所有线程。

你可以做的是尝试取消未来并中断它。第一把手InterruptedException你的未来内:

class ConnectThread implements Callbale<ApplicationConnection> { 

    public ApplicationConnection call() { 
     try { 
      return prioprietaryApi.connect(); 
     } catch(InterruptedException e) { 
      prioprietaryApi.cleanUp(); 
      throw e; 
     } 
    } 

} 

现在只需运行:

future.cancel(true); 

但是您的专有API可能无法处理InterruptedException(它不会从connect()重新抛出它,而且你可能无法访问任何cleanUp()方法

在这些情况下只是......忘了它,那Future最终会终止并自行清理,忽略事实在你不再等待它。当然这可能会导致各种可伸缩性问题。

顺便说一句,如果你想实现的唯一的事情是限制方法运行的最大时间,考虑TimeLimiter

+0

如果我正确地理解了你,我现在正在做的事情会留下悬挂的线索,但最终未来将终止并清理自己?包含future.cancel(true)只有在connect()方法可以处理InterruptedException时才有用? – Greg

+0

@Greg:你不再等待“未来”并不意味着它不再运行。当它结束时,它将像往常一样清理,但是没有人真的在等待结果。 –

1

javadoc

尝试停止所有正在执行的任务,暂停 等待任务的处理,并返回那个正在等待 执行的任务列表。除了竭尽全力尝试阻止处理主动执行任务之外,没有任何保证。例如,典型的 实现将通过Thread.interrupt()取消,因此任何 未能响应中断的任务都可能永远不会终止。

+0

所以在说,你是说任何产生的线程也应该结束时关闭服务与shutdownNow?如果我要使用关机,那么在Executor服务关闭之前,一切都会完成(包括产生)? – Greg

+0

不,shutdownNow()不保证,shutdown()保证了这种行为。 – kosa