7

我一直在做一个项目,我的程序在执行期间创建了大约 500 个线程。我发现我的电脑一执行程序就开始承受巨大的负载。在 75% 的线程完成工作后,它会继续显示负载。我想知道工作完成的线程是否被杀死。以及 java 如何处理已完成工作的线程。任何帮助...

4

5 回答 5

9

我发现我的电脑一执行程序就开始承受巨大的负载。在 75% 的线程完成工作后,它会继续显示负载。

如果 500 个线程中有 75% 已完成其工作,那么剩下的 100+ 个线程将继续运行。100 个线程,如果使用大量 CPU,可以超过我认为没有 100 个内核的盒子上的处理器。因此,您的应用程序可能会继续显示 100% 的 CPU 利用率,直到正在运行的线程数低于内核数。

您应该考虑使用固定大小的线程池,而不是创建 500 个并发线程。然后将 500 个任务提交到线程池。这允许您选择适当数量的线程同时运行。适当数量的线程高度依赖于提交的任务。更多的 CPU 绑定任务应该使用更少的线程,而 IO 绑定的任务可以使用更多。在调整线程数的同时对您的应用程序进行一些测试运行是优化值的最佳方式。我倾向于从 2 倍的核心数量开始,然后从那里进行优化。

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// define your jobs somehow
for (MyRunnable job : jobsToDo) {
    threadPool.submit(job);
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();

有关更多详细信息,请查看ExecutorService教程

我想知道工作完成的线程是否被杀死。以及 java 如何处理已完成工作的线程。任何帮助...

线程很可能已经完成。在线程离开run()方法后(因为它返回或抛出异常),它将不再消耗 CPU,并且其底层的本机线程可以被回收或重用。如果没有对该Thread对象的引用,它的内存最终会被垃圾收集器回收。

于 2013-11-13T18:05:15.043 回答
4

Thread只要没有对它的引用,并且只要它的 run 方法返回,JVM 就会对对象进行垃圾收集。线程在它的 run 方法返回后本身就死了。它可能仍然在堆中,但它不再拥有自己的堆栈,并且不做任何事情。

您的线程没有被杀死的唯一可能方法是它们仍然在做某事,或者您忘记清理对线程对象的引用 - 但这是与内存相关的。

如果您通过线程池分配线程,它们会在任务执行后返回到池中。我这种情况下,任务完成后他们可能不会被释放。

于 2013-11-13T17:56:01.587 回答
1

我们不应该创建很多线程来完成我们的任务,它会给你很多问题,比如 OutofMemoryError。而且创建线程也是一项代价高昂的任务,因此我们应该考虑线程池,即ExecutorService我们在其中一次又一次地重用相同的线程。

但是任何在创建线程后回答你问题的方法都会自动死亡,即它将被垃圾收集,你不需要做任何事情。最初 java 提供了类似stop()or的方法,destroy()但出于充分的理由,这些方法已被弃用。

于 2013-11-13T17:56:40.213 回答
1

您可以阅读有关线程生命周期的信息。如果 run 方法结束,那么他们不应该消耗你的 cpu。

于 2013-11-13T18:03:32.770 回答
0

完成工作的线程将死亡。它不会消耗更多的 CPU 时间。

您可以使用jstack 来检查有多少线程在您的 java 进程中运行。

于 2013-11-13T17:55:10.277 回答