我知道这个话题已经被问了很多,但我不确定一个细节。 现在,线程池不会让线程在完成任务后死亡,并在以后根据需要重用它(正如所说的 here 、 here 等) 但是假设我的可运行对象在构造函数中有变量 -
MyRunnable(int a){
this.a = a;
}
然后,当我们尝试使用 Executors.newFixedThreadPool
(或类似的东西)运行 Runnable 时,我们会说
executor.execute(new MyRunnable(a)); // executor being Executors.newFixedThreadPool
现在,如果变量“a”在每次执行中都不同,那么线程池以后真的可以重用它吗? 我无法真正理解这是如何工作的,但我从未见过“线程池重用线程,除了......”,因此感到困惑。
最佳答案
不,您提交的Runnable
以及与其相关的变量都不会被重用。
我认为你误解了Thread
和Runnable
,它们是不同的东西。 Runnable
只是普通对象,除了当您使用它创建新线程时将执行它的 run
方法。您可以查看this question 。
线程的复用并不意味着Runnable
的复用,而是线程不断执行不同的Runnable
。
当您使用Runnable
创建一个Thread
,并像这样启动
这个线程时:
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
等参数)。
- 如果有必要,它会创建一个新的
Worker
,并将此Runnable
作为FirstTask
,并使用此创建一个新线程>Worker
并启动它。 - 如果没有,则会将
Runnbale
放入队列中。当有空闲线程时,它们会检查该队列并从中获取任务。
关于java - 线程池重用线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49964436/