在我的 Java 应用程序中,我有一个 Runnable,例如:
this.runner = new Runnable({
@Override
public void run() {
// do something that takes roughly 5 seconds.
}
});
我需要在单独的线程中大约每 30 秒运行一次(尽管这可能会有所不同)。代码的性质是这样的,我可以运行它而忘记它(无论它成功还是失败)。我在我的应用程序中按如下方式执行此操作作为一行代码:
(new Thread(this.runner)).start()
现在,这工作正常。但是,我想知道在每个线程实例完成运行后,我是否应该对它们进行任何类型的清理?我正在 VisualVM
中对此应用程序进行 CPU 分析,我可以看到,在 1 小时的运行时间中,正在创建大量线程。这种担忧是否有效或是否一切正常?
注意我开始一个 new Thread
而不是简单地将 this.runner
定义为一个 Thread
的原因是我有时需要运行 this .runner
同时两次(在第一次运行调用完成之前),如果我将 this.runner
定义为 Thread
,我将无法执行此操作,因为单个 Thread
对象只能在初始执行完成后再次运行。
最佳答案
使用后需要“清理”或“关闭”的 Java 对象通常会实现 AutoCloseable
界面。这使得使用 try-with-resources 进行清理变得容易. Thread
类没有实现 AutoCloseable
,并且没有“close”或“dispose”方法。因此,您不需要进行任何显式清理。
不过
(new Thread(this.runner)).start()
不保证立即开始计算Runnable
。您可能不关心它是成功还是失败,但我想您确实关心它是否运行。您可能希望限制并发运行的这些任务的数量。例如,您可能希望一次只运行一个。所以你可能想要 join()
线程(或者,也许是 join with a timeout )。加入线程将确保线程将完成其计算。使用超时加入线程会增加线程开始其计算的机会(因为当前线程将被挂起,释放可能运行其他线程的 CPU)。
但是,不建议创建多个线程来执行常规或频繁的任务。你应该改为 submit任务 thread pool .这将使您能够控制并发的最大数量,并且可以为您提供其他好处(例如区分不同任务的优先级),并摊销 expense of creating threads .
您可以将线程池配置为使用固定长度(有界)的任务队列,并导致将线程提交到 execute submitted tasks itself themselves当队列已满时。通过这样做,您可以保证提交给线程池的任务(最终)被执行。 ThreadPool.execute(Runnable)
的文档说是
Executes the given task sometime in the future
这表明实现保证它最终将运行所有提交的任务即使您不执行那些特定任务以确保提交的任务得到执行。
关于java - 我需要清理 Java 中的 Thread 对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58299070/