我刚刚开始查看Java的Executors
类和newCachedThreadPool( )
方法。根据API,生成的线程池会重用现有的Thread
个对象来执行新任务。
我有点疑惑这是如何实现的,因为我在Thread
API中找不到任何允许您设置现有Thread
对象行为的方法。
例如,您可以从Thread
对象创建新 Runnable
,这会使Thread
调用Runnable
'{ {1}}方法。但是,run( )
API中没有以Thread
作为参数的setter方法。
我很感激任何指示。
答案 0 :(得分:24)
基本上想象池中的每个线程都这样做:
public void run() {
while(true) {
if(tasks available) {
Runnable task = taskqueue.dequeue();
task.run();
} else {
// wait or whatever
}
}
}
答案 1 :(得分:4)
线程池具有查找可运行作业的线程。而不是从Runnable
开始新线程,线程将只调用函数run()
。因此,ThreadPool
中的线程不是使用您提供的Runnable
创建的,而是使用仅检查是否已准备好执行任何任务并直接调用它们的线程。
所以它看起来像这样:
while(needsToKeepRunning()){
if(hasMoreTasks()){
getFirstTask().run();.
}
else
{
waitForOtherTasks();
}
}
当然这是过度简化的实际实现,等待更优雅。有关这如何运作的重要信息来源可以在Concurrency in Practice
中找到答案 2 :(得分:3)
在线程池API中创建仅一次(由于某些异常导致线程突然退出)
工作线程轮询队列以查看是否有任务并使用它。所以线程永远不会退出。
它只是一个抽象,线程被重用(抽象,他们永远不会实际停止)。显然它们在空闲超时和关闭请求后停止。
Runnable ----->线程池(某些工作线程消耗Runnable和其他人等待更多Runnables)
答案 3 :(得分:2)
执行官在后台为您完成所有事情。是的,它只使用现有的线程API。
下面的链接包含使用Thread类和Collection API实现的线程池的示例实现:http://www.ibm.com/developerworks/library/j-jtp0730/index.html
答案 4 :(得分:2)
线程只需要在分配给他的runnables上调用Runnable.run()
......
答案 5 :(得分:2)
简化说明是,当您将Runnable传递给ExecutorService时,Runnable将被放入队列中。 ThreadPool工作线程从此队列读取并调用排队的Runnables run()方法。