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

问题描述 投票:1回答:2

在我的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小时的运行时间过程中,正在创建许多线程。这种关注有效吗?还是一切正常?

N.B。我启动new Thread而不是简单地将this.runner定义为Thread的原因是,有时我需要同时运行两次this.runner(在第一次运行调用完成之前),而我不能这样做如果我将this.runner定义为Thread,因为单个Thread对象只能在初始执行完成后才能再次运行。

java multithreading concurrency runnable
2个回答
2
投票

使用后需要“清理”或“关闭”的Java对象通常会实现AutoCloseable接口。这使使用AutoCloseable进行清理变得容易。 try-with-resources类不实现Thread,并且没有“关闭”或“处置”方法。因此,您无需进行任何显式清理。

但是

Thread

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

但是,不建议创建多个线程来执行常规或频繁任务。您应该将join()任务分配给join()。这将使您能够控制最大的并发量,并可以为您带来其他好处(例如,优先处理不同的任务)。

您可以配置线程池以使用固定长度(bounded)任务队列,并在队列已满时导致将线程提交到join with a timeout。这样,您可以保证(最终)执行提交给线程池的任务。 submit的文档说

将来执行给定任务

这表明实现保证了它最终将运行所有提交的任务即使],您也不必执行那些特定的任务来确保提交的任务得以执行。


0
投票

我建议您查看并发API。有许多通用的预定义方法。通过使用ExecutorService,您可以在将任务提交给执行者后调用shutdown方法,该执行者停止接受新任务,等待先前提交的任务执行,然后终止执行者。简短介绍:thread pool

© www.soinside.com 2019 - 2024. All rights reserved.