ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(2, 4,3,TimeUnit.SECONDS, new ArrayBlockingQueue(3),new ThreadPoolExecutor.CallerRunsPolicy()); 我定义的最大线程数是4个,但是为什么会有5个线程启动(先启动2个,然后队列里加3个任务,接下来启动了3个线程)???
new ThreadPoolExecutor(2, 4,3,TimeUnit.SECONDS, new ArrayBlockingQueue(3),new ThreadPoolExecutor.CallerRunsPolicy()); 我定义的最大线程数是4个,但是为什么会有5个线程启动(先启动2个,然后队列里加3个任务,接下来启动了3个线程)???
public class TestThreadPool {
//private static int produceTaskSleepTime = 2;
private static int consumeTaskSleepTime = 2000;
private static int produceTaskMaxNumber = 10;
public static void main(String[] args) {
//构造一个线程池
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(2, 4,3,TimeUnit.SECONDS, new ArrayBlockingQueue(3),new ThreadPoolExecutor.CallerRunsPolicy());
for(int i=1;i<=15;i++){
try {
//产生一个任务,并将其加入到线程池
String task = "task@ " + i;
Calendar c = Calendar.getInstance();
c.setTimeInMillis(new Date().getTime());
SimpleDateFormat dateFormat = new SimpleDateFormat("mm:ss");
System.out.println("设置任务.........: " +task+" "+c.getTime());
threadPool.execute(new ThreadPoolTask(task));
Thread.sleep(2000);
//便于观察,等待一段时间
//Thread.sleep(produceTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
下面是 ThreadPoolTask类:public class ThreadPoolTask implements Runnable,Serializable{
private static final long serialVersionUID = 0;
//保存任务所需要的数据
private Object threadPoolTaskData;
ThreadPoolTask(Object tasks){
this.threadPoolTaskData = tasks;
}
public void run(){
//处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
Calendar c = Calendar.getInstance();
c.setTimeInMillis(new Date().getTime());
SimpleDateFormat dateFormat = new SimpleDateFormat("mm:ss");
System.out.println("...........................启动任务 ....................:"+threadPoolTaskData+" "+c.getTime());
try {
////便于观察,等待一段时间
Thread.sleep(20000);
Calendar c2 = Calendar.getInstance();
c2.setTimeInMillis(new Date().getTime());
System.out.println("............................................................运行完毕: .."+threadPoolTaskData+" "+c2.getTime());
} catch (Exception e) {
e.printStackTrace();
}
threadPoolTaskData = null;
}
public Object getTask(){
return this.threadPoolTaskData;
}
}
输出结果:设置任务.........: task@ 1 Wed Jun 13 14:56:17 CST 2012
...........................启动任务 ....................:task@ 1 Wed Jun 13 14:56:17 CST 2012
设置任务.........: task@ 2 Wed Jun 13 14:56:19 CST 2012
...........................启动任务 ....................:task@ 2 Wed Jun 13 14:56:19 CST 2012
设置任务.........: task@ 3 Wed Jun 13 14:56:21 CST 2012
设置任务.........: task@ 4 Wed Jun 13 14:56:23 CST 2012
设置任务.........: task@ 5 Wed Jun 13 14:56:25 CST 2012
设置任务.........: task@ 6 Wed Jun 13 14:56:27 CST 2012
...........................启动任务 ....................:task@ 6 Wed Jun 13 14:56:27 CST 2012
设置任务.........: task@ 7 Wed Jun 13 14:56:29 CST 2012
...........................启动任务 ....................:task@ 7 Wed Jun 13 14:56:29 CST 2012
设置任务.........: task@ 8 Wed Jun 13 14:56:31 CST 2012
...........................启动任务 ....................:task@ 8 Wed Jun 13 14:56:31 CST 2012
............................................................运行完毕: ..task@ 1 Wed Jun 13 14:56:37 CST 2012
...........................启动任务 ....................:task@ 3 Wed Jun 13 14:56:37 CST 2012
............................................................运行完毕: ..task@ 2 Wed Jun 13 14:56:39 CST 2012
...........................启动任务 ....................:task@ 4 Wed Jun 13 14:56:39 CST 2012
............................................................运行完毕: ..task@ 6 Wed Jun 13 14:56:47 CST 2012
...........................启动任务 ....................:task@ 5 Wed Jun 13 14:56:47 CST 2012
............................................................运行完毕: ..task@ 7 Wed Jun 13 14:56:49 CST 2012
............................................................运行完毕: ..task@ 8 Wed Jun 13 14:56:51 CST 2012
设置任务.........: task@ 9 Wed Jun 13 14:56:53 CST 2012
设置任务.........: task@ 10 Wed Jun 13 14:56:55 CST 2012
............................................................运行完毕: ..task@ 3 Wed Jun 13 14:56:57 CST 2012
...........................启动任务 ....................:task@ 9 Wed Jun 13 14:56:57 CST 2012
设置任务.........: task@ 11 Wed Jun 13 14:56:57 CST 2012
............................................................运行完毕: ..task@ 4 Wed Jun 13 14:56:59 CST 2012
...........................启动任务 ....................:task@ 10 Wed Jun 13 14:56:59 CST 2012
设置任务.........: task@ 12 Wed Jun 13 14:56:59 CST 2012
设置任务.........: task@ 13 Wed Jun 13 14:57:01 CST 2012
设置任务.........: task@ 14 Wed Jun 13 14:57:03 CST 2012
...........................启动任务 ....................:task@ 14 Wed Jun 13 14:57:03 CST 2012
设置任务.........: task@ 15 Wed Jun 13 14:57:05 CST 2012
...........................启动任务 ....................:task@ 15 Wed Jun 13 14:57:05 CST 2012
............................................................运行完毕: ..task@ 5 Wed Jun 13 14:57:07 CST 2012
...........................启动任务 ....................:task@ 11 Wed Jun 13 14:57:07 CST 2012
............................................................运行完毕: ..task@ 9 Wed Jun 13 14:57:17 CST 2012
...........................启动任务 ....................:task@ 12 Wed Jun 13 14:57:17 CST 2012
............................................................运行完毕: ..task@ 10 Wed Jun 13 14:57:19 CST 2012
...........................启动任务 ....................:task@ 13 Wed Jun 13 14:57:19 CST 2012
............................................................运行完毕: ..task@ 14 Wed Jun 13 14:57:23 CST 2012
............................................................运行完毕: ..task@ 15 Wed Jun 13 14:57:25 CST 2012
............................................................运行完毕: ..task@ 11 Wed Jun 13 14:57:27 CST 2012
............................................................运行完毕: ..task@ 12 Wed Jun 13 14:57:37 CST 2012
............................................................运行完毕: ..task@ 13 Wed Jun 13 14:57:39 CST 2012我不理解的是:
...........................启动任务 ....................:task@ 8 Wed Jun 13 14:56:31 CST 2012
为什么启动task 8 , 这样不是有五个线程了吗?
............................................................运行完毕: ..task@ 1 Wed Jun 13 14:56:37 CST 2012 task@1的完成了才执行的task8
多线程的打印具有一定的不确定性,楼主用Semaphore信号量来确定同一时间一共几个线程在启动。
仔细看了下CallerRunsPolicy的解释: A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method
哪个线程调这个任务就在哪个线程里执行,主线程调的,所以主线程停止for循环,先来把这个任务做了,然后在循环后面的,,嘎嘎