【发布时间】:2012-08-05 21:12:40
【问题描述】:
我认为使用ThreadPoolExecutor 我们可以提交Runnables 以在构造函数中传递的BlockingQueue 或使用execute 方法中执行。
我的理解是,如果有任务可用,它将被执行。
我不明白的是:
public class MyThreadPoolExecutor {
private static ThreadPoolExecutor executor;
public MyThreadPoolExecutor(int min, int max, int idleTime, BlockingQueue<Runnable> queue){
executor = new ThreadPoolExecutor(min, max, 10, TimeUnit.MINUTES, queue);
//executor.prestartAllCoreThreads();
}
public static void main(String[] main){
BlockingQueue<Runnable> q = new LinkedBlockingQueue<Runnable>();
final String[] names = {"A","B","C","D","E","F"};
for(int i = 0; i < names.length; i++){
final int j = i;
q.add(new Runnable() {
@Override
public void run() {
System.out.println("Hi "+ names[j]);
}
});
}
new MyThreadPoolExecutor(10, 20, 1, q);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("++++++++++++++");
}
}); */
for(int i = 0; i < 100; i++){
final int j = i;
q.add(new Runnable() {
@Override
public void run() {
System.out.println("Hi "+ j);
}
});
}
}
}
除非我在构造函数中取消注释executor.prestartAllCoreThreads();,或者我调用打印System.out.println("++++++++++++++"); 的runnable 的execute(它也被注释掉),否则这段代码不会做任何事情。
为什么?
引用(我的重点):
默认情况下,即使是核心线程也是最初创建和仅启动 当新任务到达时,但这可以使用动态覆盖 方法 prestartCoreThread() 或 prestartAllCoreThreads()。你可能 如果您使用非空构造池,则希望预启动线程 队列。
好的。所以我的队列不是空的。但是我创建了executor,我做了sleep,然后我将新的Runnables 添加到队列中(在循环中到100)。
这个循环不算new tasks arrive吗?
为什么它不起作用,我必须prestart 或显式调用execute?
【问题讨论】:
-
工作线程在
execute到达任务时产生,这些线程与底层工作队列交互。如果您从非空工作队列开始,则需要预先启动工作人员。请参阅implementation in OpenJDK 7。 -
@veer:是的,我知道。但是我从一个非空队列开始,然后开始添加到队列中。为什么我需要预先启动工人?为什么我每次都需要查看实施?规范是错误的,或者我无法理解它。那么它是什么?
-
同样,工人是直接与队列交互的人。它们仅在通过
execute(或其上方的层,例如invokeAll、submit等)传递时按需生成。见executehere的代码。 -
@veer:当我预启动工作人员时,代码无需调用
execute即可运行 -
是的,那是因为工作人员已经启动,因此他们能够检查队列中的可用工作。
标签: java multithreading concurrency java.util.concurrent threadpoolexecutor