ThreadPoolExecutor threadPool = 
new ThreadPoolExecutor(2, 4,3,TimeUnit.SECONDS, new ArrayBlockingQueue(3),new ThreadPoolExecutor.CallerRunsPolicy());   我定义的最大线程数是4个,但是为什么会有5个线程启动(先启动2个,然后队列里加3个任务,接下来启动了3个线程)???

解决方案 »

  1.   

    我就是想问为什么会有五个启动,下面是我的测试片段:
    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 , 这样不是有五个线程了吗?
      

  2.   

    直接看输入是不准确的,打印需要时间,其实
    ............................................................运行完毕: ..task@ 1 Wed Jun 13 14:56:37 CST 2012 task@1的完成了才执行的task8
    多线程的打印具有一定的不确定性,楼主用Semaphore信号量来确定同一时间一共几个线程在启动。
      

  3.   

    后来我直接执行任务的时候把线程名字打印出来发现 第五个线程其实是主线程main,百思不得其解喽,
    仔细看了下CallerRunsPolicy的解释: A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method
    哪个线程调这个任务就在哪个线程里执行,主线程调的,所以主线程停止for循环,先来把这个任务做了,然后在循环后面的,,嘎嘎