我不完全理解,我应该如何在偶尔即将到来的任务的应用程序中实现ExecutorService。每项任务运行约15分钟(长20倍)。有时一天有10个任务,有时一整周都没有。
因此,在执行了一些任务之后,如果队列中没有剩余的任务,我想关闭执行器,因为它不再需要了,这样垃圾收集器就可以继续它的工作。调用shutdown后,没有新任务排队等待执行器。
现在,我的问题是,我必须确保所有的任务都完成了。这意味着,在调用关闭后,我必须确保在提交新任务之前实例化了新的执行器服务。我必须等到旧的执行者服务关闭(或终止?)并初始化一个新的。我应该如何实现这一点?
这是我的方法:
// sync block to check for each task if a new Executor Service has to be created before submitting the task
synchronized (this) {
// do I have to check both isSutdown and isTerminated?
if (null == businessTaskExecutor || businessTaskExecutor.isShutdown() || businessTaskExecutor.isTerminated()) {
// simply init a new one
businessTaskExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
} else if (businessTaskExecutor.isTerminating()) {
// the termination process has started and is not done.
// Do I have to wait for the old executor or can I simply init a new one without waiting?
while (!businessTaskExecutor.isTerminated()) { }
businessTaskExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
}
}
Future<?> future = businessTaskExecutor.submit(() -> new BusinessTaskRunnable(businessTask));
if (future.isDone() && businessTaskExecutor.getQueue().isEmpty()) {
businessTaskExecutor.shutdown();
try {
if (!businessTaskExecutor.awaitTermination(1, TimeUnit.HOURS)) {
businessTaskExecutor.shutdownNow();
}
} catch (InterruptedException ex) {
businessTaskExecutor.shutdownNow();
Thread.currentThread().interrupt();
}
}
说明:
如果执行器为null/shutdown/terminated,我将初始化一个新的执行器,到目前为止一切正常。否则,如果执行器当前正在终止(因为调用了shutdown),则执行器不会接受进一步的任务。所以我等到它被终止,然后初始化一个新的。之后我提交我的任务。。。我只在队列中没有其他任务时关闭执行器。尽管我等了一个小时,因为可能还有一个正在运行的任务。
我希望的行为有更好的实现吗?
其他信息:我使用ThreadPoolExecutor,因为我需要getQueue()来检查它是否为空。我还可以在不同的实现中使用任何其他类型的Executor服务。
提前感谢。
我想关闭执行器,因为它不再需要了,这样垃圾收集器就可以工作了。
但它是需要的,这就是为什么你要重新创建它。无论执行器是否关闭,GC都可以完成它的工作(除非您已经设法用ThreadLocal
创建了一些非常特殊的东西,以某种方式将对象绑定到执行器)。
我读到只有在我关闭执行器时才会调用垃圾收集器。
你要么记错了,要么读到了不好的信息。
因为您使用的是单个线程,所以实际上不需要担心池的配置。一个长寿命的执行者。新固定线程池(1) 就是你所需要的。
如果确实需要释放资源,可以使用新的ThreadPoolExecutor(0,1,30,TimeUnit.SECONDS,new LinkedBlockingQueue)之类的工具来配置核心池大小
问题内容: 我不能使用,因为有可能在等待时将新任务添加到ThreadPoolExecutor中。 因此,我正在寻找一种方法,等待ThreadPoolExecutor清空队列并完成所有任务,而又不阻止在此之前添加新任务。 如果有什么不同,这适用于Android。 谢谢 更新 :几周后,我再次进行了修改,发现在这种情况下,修改后的CountDownLatch对我而言效果更好。我会保留答案,因为它更适用
网上有不少关于这个错误的帖子。我的情况是,我有时可以建立连接,但大多数时候失败了。以下是失败时的错误: 以下是成功时的信息: 我没有很好的解释,为什么有时它能工作,而另一次却不能。在每次之前,Mate 9上启用了
问题内容: 我可以重新加载当前页面而不丢失任何表单数据吗?我用了.. 和 但是这两件事对我来说无法获得早期的表格数据。怎么了 ?手动刷新浏览器时,一切正常(我不会丢失任何表单数据)。请指导我如何解决。 这是我的完整代码… 并在我的JS文件中。 问题答案: 您可以使用各种本地存储机制在浏览器中存储此数据,例如Web Storage,IndexedDB,WebSQL(不建议使用)和File API(不
我正在编程服务,从数据库中获取数据,并通过REST服务提供这些数据。它使用spring mvc。我的数据库连接配置在属性文件中,在上下文初始化期间,spring将其作为数据源bean从中加载。 现在我的问题是-我想更改属性文件中的配置(例如更改数据库信息),但我无法重新启动应用程序服务器,因此无法加载新配置。 如何重新初始化Spring上下文或一些特定的bean,以便使用新定义的属性?
编辑问题,以包括预期行为、特定问题或错误以及重现问题所需的最短代码。这将有助于其他人回答问题。 哪里出错:< br >任务执行失败”:app:checkDevDebugAarMetadata。 无法解析配置': app: devDebugRuntime Classpath'的所有文件。无法解析net.minidev: json-Smart:[1.3.1,2.3]。需要:项目:app 我在构建项目时
我正在尝试将ChromeOptions传递给我的驱动程序以允许弹出窗口。我将TestNG与@BeforeClass、@Test和@AfterClass注释一起使用。。我正在尝试启用弹出窗口,并且使用以下方法成功地实现了这一点。 虽然这确实有效,但它会打开webdriver,然后打开另一个带有选项的驱动程序。我不希望出现两个Web驱动程序。。我只想把这些选项传递给第一个webdriver!我使用一个