我认为使用ThreadPoolExecutor,我们可以将Runnable
提交到构造函数中传递的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("++++++++++++++");
的可运行对象的execute
(也被注释掉),否则不会有任何作用。为什么呢?
引用(我强调的):
默认情况下,即使核心线程也仅在到达新任务时才被创建和启动,但可以使用方法prestartCoreThread()或prestartAllCoreThreads()来动态覆盖此行为。如果您使用一个非空队列构造池,则可能需要预启动线程。
好吧。我的队列不是空的。但是我创建了
executor
,我执行了sleep
,然后将新的Runnable
添加到队列中(在循环中到100)。这个循环不算作“到达新任务”吗?为什么它不能起作用?我必须要么
prestart
,要么显式地调用execute
吗?
execute
到达时,工作线程将被生成,并且这些线程是与底层工作队列交互的线程。如果您从非空工作队列开始,则需要预先启动工作线程。请参阅OpenJDK 7中的实现。 - obatakuexecute
(或其上层,例如invokeAll
,submit
等)传递时才会按需生成它们。请参见此处的execute
代码(http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/concurrent/ThreadPoolExecutor.java#1300)。 - obataku