6

newFixedThreadPool.setCorePoolSize() 不使用线程,创建新的线程。

说明:我为大小 2 创建了一个 newFixedThreadPool,如果这个池的两个线程都忙,我使用 setCorePoolSize() 向这个池中添加两个线程。在这个过程中,它似乎没有重用线程,或者可能正在终止一些线程并创建新的线程,我将用代码来解释。

代码:(请参阅输出了解)

public class IncreasePoolSize
{
    static ExecutorService service = null;
    public static void main(String[] args) throws JMSException, InterruptedException
    {
        int NoOfth = 2;
        int noOfTimesToInc = 0;
        System.out.println("Start");
        service = Executors.newFixedThreadPool(NoOfth);
        for (;;)
        {
            if ( ((ThreadPoolExecutor)service).getActiveCount() >= NoOfth )
            {
                if (noOfTimesToInc < 1)
                {
                    System.out.println("Increased Threads-" + (noOfTimesToInc + 1) + " time(s)");
                    NoOfth += 2;
                    System.out.println("NoOfTh-" + NoOfth);
                    ((ThreadPoolExecutor)service).setCorePoolSize(NoOfth);
                    System.out.println("Total no of theads after increasing-" + ((ThreadPoolExecutor)service).getCorePoolSize());
                    noOfTimesToInc++;
                }

            }
            else if ( ((ThreadPoolExecutor)service).getActiveCount() <= NoOfth)
            {
                service.execute(new ConcreteThread());
            }
        }
    }

}

class ConcreteThread implements Runnable
{
    public void run() 
    {
        try
        {
             System.out.println("Thread No-" + Thread.currentThread().getId());
             Thread.sleep(5000);
             System.out.println("Thread No-" + Thread.currentThread().getId() + " finished");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

一旦线程 11 和 12 开始工作,在输出中可以看到,我将数字增加 2,因此线程 13 和 14 开始工作,但之后,我总是创建新线程而不是使用线程 11 和 12 并重用线程 13和 14。

输出:(已在调试模式下运行)

Start
Thread No-11
Thread No-12
Increased Threads-1 time(s)
NoOfTh-4
Total no of theads after increasing-4
Thread No-13
Thread No-14
Thread No-11 finished
Thread No-12 finished
Thread No-13 finished
Thread No-14 finished
Thread No-15
Thread No-16
Thread No-13
Thread No-14
Thread No-15 finished
Thread No-16 finished
Thread No-13 finished
Thread No-14 finished
Thread No-17
Thread No-18
Thread No-13
Thread No-14
Thread No-17 finished
Thread No-18 finished
Thread No-13 finished
Thread No-14 finished
Thread No-19
Thread No-20
Thread No-13
Thread No-14
Thread No-19 finished
Thread No-20 finished
Thread No-13 finished
Thread No-14 finished
Thread No-21
Thread No-22
Thread No-13
Thread No-14
Thread No-21 finished
Thread No-22 finished
Thread No-13 finished
Thread No-14 finished
Thread No-23
Thread No-24
Thread No-13
Thread No-14

4

3 回答 3

6

您的代码的一个问题是您设置了核心池大小而不是最大池大小。AnewFixedThreadPool使用相同数量的核心和最大池大小,您在某种程度上违反了该合同。

如果添加:

service.setMaximumPoolSize(NoOfth);

设置核心池大小后,将按照您的预期重用相同的 4 个线程。

注意:这实际上是一个报告的错误

ThreadPoolExecutor 的构造函数并setMaximumPoolSize抛出 IllegalArgumentException 如果corePoolSize > maximumPoolSize,但setCorePoolSize没有。

于 2013-06-11T12:39:43.193 回答
2

根据javadoc Executors.newFixedThreadPool

创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。在任何时候,最多 nThreads 个线程将是活动的处理任务

因此,它不一定是创建新线程,它只是使用来自shared unbounded queue.

固定线程池给您的不是它总是使用完全相同的线程对象,而是该执行程序中工作任务的活动线程数永远不会超过池的限制。

于 2013-06-11T12:33:59.770 回答
0

如果我们去查看正在运行的实际代码,我们可以看到发生了什么。在线程池中,工作由运行此方法的工作线程完成(取自此处

final void runWorker(Worker w) {
    Runnable task = w.firstTask;
    w.firstTask = null;
    boolean completedAbruptly = true;
    try {
        while (task != null || (task = getTask()) != null) {
            w.lock();
            clearInterruptsForTaskRun();
            try {
                beforeExecute(w.thread, task);
                Throwable thrown = null;
                try {
                    task.run();
                } catch (RuntimeException x) {
                    thrown = x; throw x;
                } catch (Error x) {
                    thrown = x; throw x;
                } catch (Throwable x) {
                    thrown = x; throw new Error(x);
                } finally {
                    afterExecute(task, thrown);
                }
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

如您所见,当有任务要运行时,这将继续运行任务。但是,如果一个 Worker 用完了任务,它就会死掉,如果稍后安排更多任务,则会创建一个新的 Worker(线程)。

于 2013-06-11T12:45:30.623 回答