gpt4 book ai didi

java - 使用 ExecutorService 时正确管理内存

转载 作者:太空宇宙 更新时间:2023-11-04 06:32:47 26 4
gpt4 key购买 nike

有一个名为“ConcurrencyUtils”的实用程序类,它在内部使用 ExecutorService

private static final ExecutorService executor = Executors.newCachedThreadPool(new CommonPoolThreadFactory());

正如您所看到的,它使用一个线程池,该线程池将根据需要添加线程。问题是,如果该池中至少有一个线程(如果 util 至少使用一次),那么当主方法执行完成应用程序时,应用程序并没有关闭,因为线程仍然活着并且没有被垃圾收集......

最初我尝试使用

public static void close(){
executor.shutdown();
}

并在程序自然应该停止执行时调用它。但不能保证 main 方法是最后一个完成的方法,并且在应用程序终止之前可能还有其他任务应该完成,因此我不知道在哪里调用“close()”来清除 util 中的线程...

我想知道社区是否可以提示我一种更智能/更干净的方法来实现这一点?

ConcurrencyUtil 旨在可供任何地方使用,但我无法创建它的实例,我需要它通过静态非实例方法提供其接口(interface)。

<小时/>

更新

让我详细解释一下这个例子,ConcurrencyUtil 有自己的池实现,它提供了有用的方法来链接多个可运行对象并并行执行它们,或者让其中一些等待其他可运行对象完成然后执行...没关系,它应该是一个实用程序类,这样无论何时您想要使用 async() 或 chain() 并且不用担心它是如何工作的。

现在是示例代码:

public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("hoooooooooooook");
}
});


ConcurrencyUtil.chain()
.add(()->System.out.println("task 1"))
.add(()->System.out.println("task 2"))
.execute()
.join();

System.out.println("main finish");
}

当执行时我会得到这个:

created new thread with name [common-pool : thread-1]
created new thread with name [common-pool : thread-2]
task 1
task 2
main finish

正如您所看到的,线程池创建了两个线程并执行并发任务,但这些工作线程仍然处于 Activity 状态(处于 sleep 状态)等待新任务,这就是为什么在主执行完成后应用程序仍在运行...并且关闭 Hook 也不起作用,因为(我想)应用程序被认为是 Activity 的...

现在鉴于我不能保证 main 方法是我的退出点(它可能是一个可运行的方法,例如,如果我删除 .join() ,则完成执行),这就是为什么我不能放置 finally block 并关闭 ConcurrencyUtil...

有什么想法可以正确地做到这一点吗?

最佳答案

应用程序设计的正确方法是引入一个显式关闭过程,该过程从任何适当的地方调用。然后,此过程可以在执行程序服务上调用 shutdown(),然后调用 awaitTermination()。查看 ExecutorService 的 Javadoc 以获取完整的代码示例。

除了常规关闭协议(protocol)之外,您还可以提供 JVM 关闭 Hook ,它将再次启动相同的关闭过程。您永远不应该依赖该机制,但在出现不可预测的故障时拥有它是一件好事。

关于java - 使用 ExecutorService 时正确管理内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25868660/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com