Java Threadpool 如何重用线程以及它是如何工作的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19765904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How Threadpool re-use Threads and how it works
提问by Jayesh
My multithreading concepts are weak and trying to learn.
我的多线程概念很弱,正在努力学习。
In Java what I know is, we can't call a thread more than once:
在 Java 中,我所知道的是,我们不能多次调用一个线程:
Thread t = new Thread; //Some Runnable
t.start();
t.start(); //Illegal and throw Exception at runtime.
As far as I know, it throws exception when you call t.start()
again because the associated stack for the thread is destroyed once it goes out of run()
method and you are trying to initialize things again.
据我所知,当您t.start()
再次调用时它会抛出异常,因为线程的关联堆栈一旦退出run()
方法就会被销毁,并且您正在尝试再次初始化。
In that case, what I know about thread pool is, it gives better performance & saves time because there is no need to create new thread (I read in this).
在那种情况下,我对线程池的了解是,它提供了更好的性能并节省了时间,因为不需要创建新线程(我在此阅读)。
If there is no need to create new thread in thread pool scenario, then how it works with same thread which just finished its run method, will that thread can be used again?
如果在线程池场景中不需要创建新线程,那么它如何与刚刚完成其run方法的同一线程一起工作,该线程是否可以再次使用?
I read this, and it says that "Most of the executor implementations in java.util.concurrent use thread pools, which consist of worker threads. This kind of thread exists separately from the Runnable and Callable tasks it executes and is often used to execute multiple tasks."
我读了这篇文章,它说“ java.util.concurrent 中的大多数执行器实现都使用线程池,它由工作线程组成。这种线程与它执行的 Runnable 和 Callable 任务分开存在,并且经常用于执行多项任务。”
So what is Worker thread here, is it something different then normal Java threads?
那么这里的 Worker 线程是什么,它和普通的 Java 线程有什么不同吗?
With thislink, I got something but still confused on what kind of stuff can be eliminated when we use thread pool and why it gives better performance than using normal java threads.
通过这个链接,我得到了一些东西,但仍然对使用线程池时可以消除哪些类型的东西以及为什么它比使用普通 Java 线程提供更好的性能感到困惑。
So can we say like this,
所以我们可以这样说,
Thread has three parts,
线程分为三个部分,
- Creation (Telling OS that it is new thread, create stack for it.)
- Execute Runnable with run() method.
- Destroying threads.
- 创建(告诉操作系统它是新线程,为其创建堆栈。)
- 使用 run() 方法执行 Runnable。
- 破坏线程。
So, considering above 3 steps, With thread pool step 1 and step 3 can be eliminated after fixed number of thread creation. Only step 2 for each task will be executed that is why threadpool is faster? Can we say like this? Am I correct?
因此,考虑到以上 3 个步骤,在创建固定数量的线程后,可以消除线程池中的第 1 步和第 3 步。每个任务只会执行第 2 步,这就是线程池更快的原因?我们可以这样说吗?我对么?
采纳答案by Jon Skeet
If there is no need to create new Thread in ThreadPool scenario, then how it works with same thread which just finished its run method, will that Thread can be used again?
如果在ThreadPool场景中不需要创建新的Thread,那么它如何与刚刚完成run方法的同一个线程一起工作,那个Thread可以再次使用吗?
Simple - the original thread never actually completes. It just waits for another task to execute. In pseudo-code:
简单 - 原始线程从未真正完成。它只是等待另一个任务执行。在伪代码中:
// No, this isn't even slightly accurate! General impression only :)
while (!pool.isShutdown()) {
Runnable task = pool.waitForTaskOnQueue();
task.run();
}
(Obviously when a thread pool is shut down, it would need to stop waiting threads from waiting for another task, too - but hopefully you get the general idea.)
(显然,当线程池关闭时,它也需要停止等待线程等待另一个任务 - 但希望您能大致了解。)
回答by Trying
So, considering above 3 steps, With Threadpool step 1 and Step 3 can be eliminated after fixed number of Thread Creation. only Step 2 for each task will be executed that is why Threadpool is faster? can we say like this? am I correct?
因此,考虑到以上 3 个步骤,使用 Threadpool 步骤 1 和步骤 3 可以在固定数量的线程创建后消除。每个任务只会执行第 2 步,这就是线程池更快的原因?我们可以这样说吗?我对么?
Yes you are correct. Thread creation and destruction is one of the costly task. As in a thread pool threads are already created so the overhead of thread creation is not there. But if you have much more higher threads than it should have, it will be pretty bad for your application. It may go OutofMemorry
or may be into some other issues. So to fix a thread pool size use the below formula:
是的,你是对的。线程的创建和销毁是一项代价高昂的任务。由于在线程池中线程已经创建,因此线程创建的开销不存在。但是,如果您的线程数比应有的多得多,这对您的应用程序将非常不利。它可能会OutofMemorry
或可能会涉及其他一些问题。因此,要修复线程池大小,请使用以下公式:
no of threads = 2 * no_of_cores * no_of_disks * percentage CPU utilization you need * (1 + (W/ C))
no of threads = 2 * no_of_cores * no_of_disks * percentage CPU utilization you need * (1 + (W/ C))
(W/C) is the fraction stating Wait time to Compute time.
(W/C) 是表示等待时间到计算时间的分数。
回答by Sonu
The process workes in two parts:
该过程分为两部分:
Submission of task: Thread pools are tightly coupled with a blocking Queue. When we say executor.execute(runnable). The runnable/callable is enqued in the queue.
任务提交:线程池与阻塞队列紧密耦合。当我们说 executor.execute(runnable) 时。runnable/callable 在队列中排队。
Execution of tasks: Now the tasks need to be picked up from the queue. Lets say whenever a task is submitted in the queue, it must be picked up and executed.
任务的执行:现在需要从队列中提取任务。假设每当一个任务在队列中提交时,它就必须被拾取并执行。
So there are threads which will be running infinite loop and watching the queue for tasks. As soon as the tasks are available one thread will pick it and execute.
所以有些线程将运行无限循环并观察任务队列。一旦任务可用,一个线程就会选择它并执行。
回答by Vinayak Bansal
In Thread Pool Instead of creating new threads when new tasks arrive, a thread pool keeps a number of idle threads that are ready for executing tasks as needed. After a thread completes execution of a task, it does not die. Instead it remains idle in the pool waiting to be chosen for executing new tasks.
在线程池中,线程池不会在新任务到达时创建新线程,而是保留一些空闲线程,以便根据需要准备好执行任务。线程完成任务执行后,不会死亡。相反,它在池中保持空闲,等待被选择执行新任务。
You can limit a definite number of concurrent threads in the pool, which is useful to prevent overload. If all threads are busily executing tasks, new tasks are placed in a queue, waiting for a thread becomes available
您可以限制池中一定数量的并发线程,这有助于防止过载。如果所有线程都在忙着执行任务,新的任务被放入队列,等待线程变为可用