为了账号安全,请及时绑定邮箱和手机立即绑定

我需要清理 Java 中的 Thread 对象吗?

我需要清理 Java 中的 Thread 对象吗?

拉丁的传说 2023-10-12 16:54:31
在我的 Java 应用程序中,我有一个 Runnable,例如:this.runner = new Runnable({    @Override    public void run() {        // do something that takes roughly 5 seconds.    }});我需要大约每 30 秒在一个单独的线程中运行一次(尽管这可能会有所不同)。代码的本质是我可以运行它并忘记它(无论它成功还是失败)。我在应用程序中将其作为一行代码执行,如下所示:(new Thread(this.runner)).start()现在,这工作正常。但是,我想知道在每个线程实例完成运行后是否应该对其进行任何类型的清理?我正在对这个应用程序进行 CPU 分析VisualVM,我可以看到,在 1 小时的运行时间过程中,创建了很多线程。这种担忧是否有效,或者一切都好吗?new Thread注意我开始 a而不是简单地定义this.runner为 a的原因Thread是,我有时需要this.runner同时运行两次(在第一次运行调用完成之前),如果我定义this.runner为 a ,我就不能这样做Thread,因为单个Thread对象只能初始执行完成后再次运行。
查看完整描述

2 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

使用后需要“清理”或“关闭”的Java对象通常实现该AutoCloseable接口。这使得使用try-with-resources可以轻松地进行清理。该类Thread没有实现AutoCloseable,并且没有“close”或“dispose”方法。因此,您不需要进行任何显式清理。

然而

(new Thread(this.runner)).start()

不保证立即开始 的计算Runnable。您可能不关心它是成功还是失败,但我想您确实关心它是否运行。您可能希望限制同时运行的这些任务的数量。例如,您可能只想一次运行一个。所以你可能想要join()线程(或者,也许,加入超时)。加入线程将确保线程完成其计算。以超时方式加入线程会增加线程开始计算的机会(因为当前线程将被挂起,从而释放可能运行其他线程的 CPU)。

但是,不建议创建多个线程来执行常规或频繁任务。您应该将任务提交到线程池。这将使您能够控制最大并发量,并且可以为您提供其他好处(例如区分不同任务的优先级),并分摊创建线程的费用。

您可以将线程池配置为使用固定长度(有界)任务队列,并让提交线程在队列已满时自行执行已提交的任务。通过这样做,您可以保证提交到线程池的任务(最终)被执行。的文档ThreadPool.execute(Runnable)说明了这一点

在将来的某个时间执行给定的任务

这表明该实现保证它最终会运行所有提交的任务,即使您不执行这些特定任务以确保执行提交的任务。


查看完整回答
反对 回复 2023-10-12
?
慕村225694

TA贡献1880条经验 获得超4个赞

我建议您查看并发 API。有许多预定义的通用方法。通过使用 ExecutorService,您可以在向执行器提交任务后调用 shutdown 方法,该方法会停止接受新任务,等待之前提交的任务执行,然后终止执行器。

查看完整回答
反对 回复 2023-10-12
  • 2 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信