【问题标题】:What happens to a thread as soon as it has completed its assigned task in java?线程在java中完成分配的任务后会发生什么?
【发布时间】:2013-11-26 11:14:38
【问题描述】:

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

【问题讨论】:

  • 您是否考虑过不同的设计,例如将您的任务提交到固定(或有限大小)ThreadPoolExecutor,而不是给每个任务单独的线程?
  • 您能详细说明所涉及的计算吗?当您需要 500 个并发线程时,没有多少情况(即爬行)......
  • 我一直在开发一个扫描网络共享资源的应用程序。我为网络上的每个节点使用了一个单独的线程来检查共享资源以及节点上是否有共享资源(我在 jCIFS 的帮助下检查),该线程中的一个线程将运行以遍历共享文件夹的树并将信息存储在本地文件系统中。

标签: java multithreading


【解决方案1】:

我发现我的电脑在执行程序后就开始承受巨大的负载。在 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 tutorial

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      您可以阅读Thread's lifecycle。如果 run 方法结束了,那么它们不应该消耗你的 cpu。

      【讨论】:

        【解决方案4】:

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

        但是在创建线程后回答您问题的任何方法都会自动死亡,即它将被垃圾收集,您无需执行任何操作。最初 java 提供了诸如 stop()destroy() 之类的方法,但出于充分的理由,这些方法已被弃用。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-12
            • 2011-12-23
            • 1970-01-01
            • 1970-01-01
            • 2018-12-11
            • 2015-01-29
            • 2012-03-19
            • 2015-02-13
            相关资源
            最近更新 更多