Threadpool如何重用Threads及其工作原理

时间:2013-11-04 10:35:23

标签: java multithreading threadpool

我的多线程概念很薄弱并且正在努力学习。

在我所知道的java中,我们不能再调用一次线程,即

Thread t = new Thread(//Some Runnable);
t.start()

t.start() //Illegal and throw Exception at Runtime.

据我所知,当你再次调用t.start()时会抛出异常,因为一旦它离开run()方法并且你试图再次初始化东西,Thread的相关堆栈就会被销毁。

在这种情况下,我对Threadpool的了解是,它提供了更好的性能和优势。节省时间,因为不需要创建新线程。 (我在http://www.javatpoint.com/thread-pooling-in-java读到)

如果不需要在ThreadPool场景中创建新的Thread,那么它如何与刚刚完成其run方法的同一个线程一起工作,那么Thread是否可以再次使用?

我读了这个,http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html 并且它说“ java.util.concurrent中的大多数执行程序实现都使用由工作线程组成的线程池。这种线程与它执行的Runnable和Callable任务分开存在,通常用于执行多个任务。

那么这里的Worker线程是什么,它与普通的Java Threads有什么不同?

使用此链接How Does a Cached Thread Pool Reuse Existing Threads我得到了一些东西但仍然对使用线程池时可以消除哪种东西感到困惑,并且使用普通的Java Thread提供了更好的性能。

我们可以这样说,

线程有三个部分,

  1. 创建(告诉操作系统它是新线程,为它创建堆栈。)
  2. 执行Runnable即run()方法。
  3. 销毁线程。
  4. 因此,考虑到上述3个步骤,使用Threadpool步骤1和步骤3可以在固定数量的线程创建后消除。只执行每个任务的第2步,这就是为什么Threadpool更快?我们可以这样说吗?我是对的吗?

4 个答案:

答案 0 :(得分:30)

  

如果不需要在ThreadPool场景中创建新线程,那么它如何与刚刚完成其run方法的同一线程一起工作,那么Thread可以再次使用吗?

简单 - 原始线程从未实际完成。它只是等待执行另一个任务。在伪代码中:

// No, this isn't even slightly accurate! General impression only :)
while (!pool.isShutdown()) {
    Runnable task = pool.waitForTaskOnQueue();
    task.run();
}

(显然当一个线程池关闭时,它也需要停止等待线程等待另一个任务 - 但希望你能得到一般的想法。)

答案 1 :(得分:2)

该过程分为两部分:

提交任务:线程池与阻塞队列紧密耦合。当我们说executor.execute(runnable)时。 runnable / callable被装入队列中。

执行任务:现在需要从队列中拾取任务。可以说,无论何时在队列中提交任务,都必须将其拾取并执行。

因此,有些线程将运行无限循环并观察队列中的任务。一旦任务可用,一个线程就会选择并执行。

答案 2 :(得分:2)

在线程池中当新任务到达时,线程池不会创建新线程,而是保留许多空闲线程,这些线程已准备好根据需要执行任务。线程完成任务执行后,它不会死亡。相反,它在池中保持空闲状态,等待被选择执行新任务。

您可以限制池中确定数量的并发线程,这对防止过载非常有用。如果所有线程都忙于执行任务,则新任务将被放入队列中,等待线程变为可用

答案 3 :(得分:1)

  

因此,考虑到以上3个步骤,使用Threadpool步骤1和步骤3即可   在固定数量的线程创建后被删除。只有第2步   每个任务都将被执行,这就是为什么Threadpool更快?我们可以吗   这样说?我是对的吗?

是的,你是对的。线程创建和销毁是一项代价高昂的任务。由于在线程池中已经创建了线程,因此不存在线程创建的开销。但是如果你拥有比它应该拥有的更高的线程,那么对你的应用来说这将是非常糟糕的。它可能会OutofMemorry或可能会涉及其他一些问题。因此,要修复线程池大小,请使用以下公式:

no of threads = 2 * no_of_cores * no_of_disks * percentage CPU utilization you need * (1 + (W/ C))

(W / C)是表示计算时间的等待时间的分数。