【问题标题】:how many threads are created in this code? [duplicate]在这段代码中创建了多少个线程? [复制]
【发布时间】:2014-03-17 19:49:57
【问题描述】:

Executors.newFixedThreadPool(5) 在池中创建 5 个线程,然后在循环中创建另外 100 个线程。这种理解对吗?然后池中的 5 个线程将执行 100 个工作线程队列中的每个线程。

所以总共创建了 105 个线程?原以为只创建了5个线程,但每个Runnable也是一个线程。

ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 100; i++) {
    Runnable worker = new WorkerThread("" + i);
    executor.execute(worker);
}
executor.shutdown();

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    Executors.newFixedThreadPool(5) 在池中创建 5 个线程,然后在循环中创建另外 100 个线程。这种理解对吗?然后池中的 5 个线程将执行 100 个工作线程队列中的每个线程。

    这是不正确的。固定大小的线程池执行器将创建 5 个工作线程。您的 100 个 Runnables 都被添加到这 5 个线程从中提取的队列中。因此,在任何给定时间,您的 Runnables 中只有 5 个正在执行。有 5 个线程(加上主线程,如果您使用 Swing,可能还有 EDT,当然还有您明确创建的任何其他无关线程)。

    我以为只创建了 5 个线程,但每个 Runnable 也是一个线程。

    Runnable 不是线程。 Runnable,顾名思义,就是可以运行的东西。对于固定大小的线程池,它由池中的一个线程运行。来自Runnable 的文档(强调我的):

    Runnable 接口应由其实例打算由线程执行的任何类实现。

    我相信您的困惑的根源可能是您的Runnables 被不当命名为WorkerThread,即使它们不是线程。此外,您可能会对Thread实现 Runnable 这一事实感到困惑。实际上,这实际上意味着 ThreadRunnable,而不是 RunnableThread -- 并且 Thread 在启动之前甚至不是线程。

    【讨论】:

    • WokerThread 正在由 5 个线程之一执行其真正的工作。如果我想保持5个线程一共做了多少个任务,应该怎么做?
    • @CongminMin 为此,您必须在某处维护计数,并让每个任务在完成时增加计数。有很多方法可以实现它; all 将涉及将保持计数的某个对象的实例传递给 WorkerThread 构造函数(或在将任务放入池中之前通过其他方法进行设置)。本质上,您必须让他们在完成后调用一些“回调”方法,从而在某处增加一个计数器。执行器本身不提供确定执行任务数量的方法。
    【解决方案2】:

    Runnable 不是正在运行的线程。就此而言,CallableThread 都不是。

    只有在.start() a Thread 时才会在JVM 级别创建线程(这将.run() a Runnable.call() a Callable);在那之前,它们只是普通的、常规的对象。

    当您使用Executor 时,执行程序将管理您的Runnables 或Callables 并在可以这样做时启动“真实”线程。

    【讨论】:

    • 所以总共只有 5 个线程?可运行对象不是真正的线程。
    • 是的,就是这样;但是,还有其他由 JVM 本身创建的线程,您无法控制(运行 main() 的线程就是这样一个线程)。
    • 调用run() 不会创建线程!致电start() 即可。请更新帖子。
    • @Sourabh 是的,对不起;已编辑
    【解决方案3】:

    不要将Thread 类与线程混淆。 Java 使用Thread 类来生成线程,但它不一定是一对一的映射。

    在您的代码中,您的 WorkerThread 类似乎是 Thread 的子类。但是,Thread 也实现了Runnable,这就是您的ExecutorService 使用它的方式。它只是在它启动的 5 个线程之一中调用其 run() 方法。

    这段代码创建了多少线程?

    ExecutorService启动的所有线程。

    【讨论】:

      【解决方案4】:

      Runnable 只是一个interface,就像任何其他interface 一样。 Thread 也只是一个类而不是一个单独的线程。在调用 Thread 类的 start() 方法之前,不会创建实际的线程。

      【讨论】:

        【解决方案5】:

        “池中的线程数将固定。如果请求的数量超过线程数,它们将在队列中等待。如果线程死亡或终止,将创建一个新线程。” More here

        在这种情况下,最多只能存在 5 个线程。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-22
          • 2020-09-12
          • 1970-01-01
          • 1970-01-01
          • 2019-08-22
          • 2013-11-01
          • 2014-02-03
          • 1970-01-01
          相关资源
          最近更新 更多