【问题标题】:ExecutorService.shutdownNow() setting variables as nullExecutorService.shutdownNow() 将变量设置为空
【发布时间】:2012-11-07 17:42:33
【问题描述】:

我正在创建一个ExecutorService

ExecutorService executor = Executors.newFixedThreadPool(5);

然后我用

添加Runnables
executor.execute(runnable)

我有一个 java.sql.Connection 实例,它是在可运行实现中的某处创建的,并在 finally 语句中关闭。

在我致电 executor.shutdownNow() 之前,这一切正常。当我这样做时,连接的值为 null,即,使用检查器时,我看到 connection = null。 如果我用shutdown() 方法停止执行程序,一切都会完美运行。

我一直在搜索和阅读(甚至是 java 的源代码),但不明白是什么原因造成的。

我试图捕捉InterrupedException,但显然没有被抛出

【问题讨论】:

  • 不,执行者将此设置为空。您的代码中的某些逻辑路径很可能会发生您意想不到的情况。显示一些示例代码。请注意,当您使用shutdownNow() 时,某些任务可能永远不会执行
  • 另请注意,shutdownNow() 会中断所有正在运行的任务,这可能会导致在创建连接之前在 finally 块中抛出一些东西。
  • shutdownNow() 不应该优雅地终止正在运行的任务吗?这是我的理解......实际上,我没有看到任何异常被抛出,我正在记录每一个抛出的异常
  • 你还没有展示任何相关的代码,所以很难给出更具体的指针。不确定“优雅地终止正在运行的任务”是什么意思,但shutdownNow() 肯定会中断它们(使用标准的 java 线程中断)。
  • 被中断的线程不一定会抛出异常并退出。这一切都取决于中断的代码,它可能会捕获 InterruptedException,记录它,将连接字段设为 null ...

标签: java multithreading runnable executorservice


【解决方案1】:

由于我们对shutdownNow() 对您产生的不良副作用一无所知...
通常,shutdown() 应该足以导致ExecutorService 拒绝新作业,并且工作线程完成队列中剩余的作业。不幸的是,shutdown()(它将让所有先前提交的作业完成)和shutdownNow()(将尝试中断当前正在执行的作业)之间似乎存在差距。应该有一个介于两者之间的shutdownAlmostNow() 让 ES 完成他们当前的工作,但返回那些仍在等待的工作,如shutdownNow()


如果您使用ThreadPoolExecutor,您可以调用shutdown(),获取作业队列并将其排空,因此不会接受新作业并且旧作业会从队列中移除。然后您可以等待当前作业的终止。

【讨论】:

    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2020-08-07
    • 2014-01-02
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    相关资源
    最近更新 更多