Java线程存储



因此,我有一个循环,在其中我创建了数千个线程来处理我的数据。

我检查了一下,存储一个线程会减慢我的应用程序的速度。

它来自我的循环:

Record r = new Record(id, data, outPath, debug);
//r.start();
threads.add(r);
//id is 4 digits
//data is something like 500 chars long

它会让我的for循环停止一段时间(一次跑步需要一秒钟或更长时间,太多了!)。

仅初始化>持续时间:0:00:06.369

将线程添加到ArrayList>持续时间:0:00:07.348


问题:

  • 存储线程的最佳方式是什么
  • 如何使线程更快
  • 我应该创建线程并用特殊的执行器运行它们吗?例如,一次运行10个线程,然后再运行10个等等。?(如果是,那么怎么做?)

考虑一下,拥有非常多的线程并不是很有用。

至少你可以同时执行相当于cpu核心数量的线程。

最好的方法是重用现有线程。要做到这一点,您可以使用Executor框架。

例如,要创建一个内部最多处理10个线程的Executor,您可以执行以下操作:

List<Record> records = ...;
ExecutorService executor = Executors.newFixedThreadPool(10);
for (Record r : records) {
   executor.submit(r);
}
// At the end stop the executor
executor.shutdown();

使用与此类似的代码,您还可以提交数千个命令(可运行的实现),但创建的线程不超过10个。

我猜真正让你慢下来的不是.add方法。我的猜测是,数百个线程并行运行才是真正的问题所在。当然,像"add"这样的简单命令将在管道中排队,并且可能需要很长时间才能执行,即使执行本身很快。此外,您的数据结构可能有一个位于O(n)中的add方法。

可能的解决方案:*找到一个真正的免费解决方案。例如,对线程进行优先级排序。*在执行之前,将它们全部添加到您的数据结构中

虽然可以这样工作,但强烈建议不要为这样的东西创建更多的线程。正如David Lorenzo已经指出的那样,您应该使用线程执行器。

我有一个循环,我在其中创建了数千个线程。。。

这是个坏兆头。创建线程的成本很高。

假设您的程序创建了数千个线程,因为它有数千个任务要执行。诀窍是,将线程与任务解耦。只创建几个线程,然后重用它们。

这就是线程池为您所做的。

了解java.util.concurrent.ThreadPoolExecutor类和相关类(例如Future)。它实现了一个线程池,很可能它提供了您需要的所有功能。

如果您的需求足够简单,您可以使用java.util.concurrent.Executors中的一种静态方法来创建和配置线程池。(例如,Executors.newFixedThreadPool(N)将创建一个新的线程池,其中正好有N个线程。)

如果你的任务都是计算绑定的,那么没有理由拥有比机器中CPU数量更多的线程。如果您的任务花费时间等待(例如,等待来自网络客户端的命令),那么创建多少线程的决定将变得更加复杂:这取决于这些线程使用了多少资源。你可能需要试验才能找到正确的数字。

最新更新