Executor的'执行(Runnable命令)'方法究竟做了什么?

时间:2013-11-27 08:35:22

标签: java

private ExecutorService executor1 = Executors.newFixedThreadPool(5); 

 for(int i=0;i<10;i++)
  executor1.execute(some runnable command); 

有谁可以解释上述两个陈述中究竟发生了什么?在哪个语句中创建了一个新线程?创建了多少个新线程?

3 个答案:

答案 0 :(得分:1)

创建新的固定线程池时会创建线程,但这些线程还没有执行任何操作。他们站在旁边等着执行任务。

当您告诉固定的线程池执行程序执行Runnable时,该runnable将被发送到其中一个空闲线程,然后它将开始与程序执行并行运行。当Runnable终止时,完成的线程再次处于待机状态并等待进一步的工作。

当你告诉执行者服务在池中的所有线程都忙时执行runnables时,那些runnables将被放入队列并在runnable完成时执行。

答案 1 :(得分:0)

执行程序消息将执行您在另一个线程中指定的runnable。

private ExecutorService executor1 = Executors.newFixedThreadPool(5);

表示您正在其线程池中创建一个包含5个线程的执行程序对象。因此,当有请求进入时,它将使用这五个中的一个线程并执行请求。

for(int i=0;i<10;i++)
  executor1.execute(some runnable command); 

此声明表示您正在为执行程序服务提供10个任务。由于执行程序有5个线程,它将开始执行前五个任务,后续任务将被安排执行。也就是说,当前五个任务完成后,该线程将返回线程池,然后分配给执行第6个任务。

例如:

线程1:执行任务1

线程2:执行任务2

线程3:执行任务3

主题4:执行任务4

线程5:执行任务5

假设线程3完成其工作,然后:

线程3:执行任务6

然后假设线程1完成其工作:

线程1:执行任务7

依旧......

直到所有预定的任务完成。由于线程池大小为5,因此一次最多只能完成5个并行任务。希望我的解释能帮到你。

答案 2 :(得分:0)

查看ThreadPoolExecutor.execute()方法的源代码。

方法1:检查ThreadPool大小和池运行状态。

    public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
        if (runState == RUNNING && workQueue.offer(command)) {
            if (runState != RUNNING || poolSize == 0)
                ensureQueuedTaskHandled(command);
        }
        else if (!addIfUnderMaximumPoolSize(command))
            reject(command); // is shutdown or saturated
    }
}

方法2:

    private void ensureQueuedTaskHandled(Runnable command) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    boolean reject = false;
    Thread t = null;
    try {
        int state = runState;
        if (state != RUNNING && workQueue.remove(command))
            reject = true;
        else if (state < STOP &&
                 poolSize < Math.max(corePoolSize, 1) &&
                 !workQueue.isEmpty())
            t = addThread(null);
    } finally {
        mainLock.unlock();
    }
    if (reject)
        reject(command);
    else if (t != null)
        t.start();
}

方法3:使用runnalbe.run()方法创建和启动线程。

 private Thread addThread(Runnable firstTask) {
    Worker w = new Worker(firstTask);
    Thread t = threadFactory.newThread(w);
    if (t != null) {
        w.thread = t;
        workers.add(w);
        int nt = ++poolSize;
        if (nt > largestPoolSize)
            largestPoolSize = nt;
    }
    return t;
}