线程池重用线程
Threadpool re-use of threads
我知道这个话题已经被问了很多,但我不确定一个细节。
现在线程池不会让线程在完成任务后死亡,并在以后根据需要重用它(正如所说 here, here,等等)
但是假设我的 运行nable 在构造函数中有变量 -
MyRunnable(int a){
this.a = a;
}
然后,当我们尝试使用 Executors.newFixedThreadPool
(或类似的东西)运行 Runnable 时,我们说
executor.execute(new MyRunnable(a)); // executor being Executors.newFixedThreadPool
现在,如果变量 'a' 在每次执行中都不同,Threadpool 以后真的可以重用它吗?
我真的不明白那是如何工作的,但我从未见过 'Threadpool reuses threads except...',因此很困惑。
所以,从我的角度来看,线程池工作算法是如何相似的,如下所示
while (check if the pool is not shutdown) {
Runnable task = pool.fetchTaskFromQueue(); // fetch the Task from the queue. In your case it object of MyRunnable class
task.run(); // call the run() of MyRunnable object
}
线程池重新执行 Thread
,而不是 Runnable/ Callable
实现。因此,根据线程池,它确实重用了您的 variable a
.
不,您提交的 Runnable
以及与之相关的变量都不会被重复使用。
我想你误解了Thread
和Runnable
,它们是不同的东西。 Runnable
只是普通对象,除了它的 run
方法将在您使用它创建新线程时执行。您可以查看 this question。
线程的复用不等于Runnable
的复用,而是线程一直在执行不同的Runnable
s.
当您使用 Runnable
创建 Thread
和 start
时,此线程如下所示:
new Thread(new Runnable()).start()
这个Runnale
的run()
方法会被执行,run()
退出后,这个Thread
也会终止
但是,您提交给 ThreadPoolExecutor
的 Runnbale
不是上面构造线程的代码。
简而言之,ThreadPoolExecutor
中的线程是这样创建的:
Runnable worker = new Runnable() {
@Override
public void run() {
Runnable firstTask = getFirstTask(); // the first runnable
firstTask.run();
Runnable queuedTask;
while ( (queuedTask = getTaskFromQueue()) != null) { // This could get blocked
queuedTask.run();
}
}
};
new Thread(worker).start();
请注意,用于启动线程的 Runnable
不是您提交到池中的线程。
当你提交新的Runnable
时,线程池会检查是否需要创建新的线程(基于像corePoolSize
这样的参数)。
- 如果有必要,那么它会用这个
Runnable
创建一个新的Worker
作为FirstTask
,并用这个Worker
创建一个新线程并启动它。
- 如果没有,则将
Runnbale
放入队列中。当有空闲线程时,他们会检查这个队列并从中取任务。
我知道这个话题已经被问了很多,但我不确定一个细节。 现在线程池不会让线程在完成任务后死亡,并在以后根据需要重用它(正如所说 here, here,等等) 但是假设我的 运行nable 在构造函数中有变量 -
MyRunnable(int a){
this.a = a;
}
然后,当我们尝试使用 Executors.newFixedThreadPool
(或类似的东西)运行 Runnable 时,我们说
executor.execute(new MyRunnable(a)); // executor being Executors.newFixedThreadPool
现在,如果变量 'a' 在每次执行中都不同,Threadpool 以后真的可以重用它吗? 我真的不明白那是如何工作的,但我从未见过 'Threadpool reuses threads except...',因此很困惑。
所以,从我的角度来看,线程池工作算法是如何相似的,如下所示
while (check if the pool is not shutdown) {
Runnable task = pool.fetchTaskFromQueue(); // fetch the Task from the queue. In your case it object of MyRunnable class
task.run(); // call the run() of MyRunnable object
}
线程池重新执行 Thread
,而不是 Runnable/ Callable
实现。因此,根据线程池,它确实重用了您的 variable a
.
不,您提交的 Runnable
以及与之相关的变量都不会被重复使用。
我想你误解了Thread
和Runnable
,它们是不同的东西。 Runnable
只是普通对象,除了它的 run
方法将在您使用它创建新线程时执行。您可以查看 this question。
线程的复用不等于Runnable
的复用,而是线程一直在执行不同的Runnable
s.
当您使用 Runnable
创建 Thread
和 start
时,此线程如下所示:
new Thread(new Runnable()).start()
这个Runnale
的run()
方法会被执行,run()
退出后,这个Thread
也会终止
但是,您提交给 ThreadPoolExecutor
的 Runnbale
不是上面构造线程的代码。
简而言之,ThreadPoolExecutor
中的线程是这样创建的:
Runnable worker = new Runnable() {
@Override
public void run() {
Runnable firstTask = getFirstTask(); // the first runnable
firstTask.run();
Runnable queuedTask;
while ( (queuedTask = getTaskFromQueue()) != null) { // This could get blocked
queuedTask.run();
}
}
};
new Thread(worker).start();
请注意,用于启动线程的 Runnable
不是您提交到池中的线程。
当你提交新的Runnable
时,线程池会检查是否需要创建新的线程(基于像corePoolSize
这样的参数)。
- 如果有必要,那么它会用这个
Runnable
创建一个新的Worker
作为FirstTask
,并用这个Worker
创建一个新线程并启动它。 - 如果没有,则将
Runnbale
放入队列中。当有空闲线程时,他们会检查这个队列并从中取任务。