当前位置: 首页 > 知识库问答 >
问题:

ThreadPoolExecutor Java

闽高峯
2023-03-14

我有一个示例代码。

@Test
    public void testWithBlockQueue() throws InterruptedException {
        String poolFormat = "ServiceTaskPool-%d";
        int coreSize = 3;
        int maxSize = 3;
        int queueSize = 1;
        int idleThreadLiveInSecond = 35;

        ThreadFactory factory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r);
            }
        };
        ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(queueSize);
        final ThreadPoolExecutor service = new ThreadPoolExecutor(coreSize, maxSize, idleThreadLiveInSecond,
                TimeUnit.SECONDS, queue, factory, new ThreadPoolExecutor.AbortPolicy());
        service.allowCoreThreadTimeOut(true);
        passTask(coreSize, service);
        Thread.sleep(5000);
        passTask(coreSize, service);
        System.out.printf("Thread pool state %s", service);
        Thread.sleep(6000);
    }

    protected void passTask(int coreSize, ThreadPoolExecutor service) {
        for (int i=0; i < coreSize; i++) {
            service.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.printf("Simple printf from %s \n", Thread.currentThread().getName());
                }
            });
        }
    }

当我设置queueSize 2时,我得到了异常,因为threadpool执行器不能插入一个任务到队列中,当我设置queueSize 3时是可以的。我不明白为什么当我设置maxSize=4时,测试是可以的。它来自留档。

  1. 如果线程数小于corePoolSize,请创建一个新线程以运行新任务
  2. 如果线程数等于(或大于)corePoolSize,则将任务放入队列
  3. 如果队列已满,且线程数小于maxPoolSize,请创建一个新线程以在其中运行任务
  4. 如果队列已满,且线程数大于或等于maxPoolSize,请拒绝该任务

共有1个答案

巴帅
2023-03-14

事实上,当maxSize=4时,可能会引发异常

第一次调用passTask(coreSize,service),我们得到task1、task2、task3。将创建thread1、thread2、thread3来运行它们。

第二次调用passTask(coreSize,service):

>

2.1. 如果task4仍在队列中,则将创建thread4并运行task5;

2.2. 如果线程1、线程2或线程3已从队列中获取task4,则task5将被放入队列中。

i=2, whe get task6.

3.1. 如果task4仍在队列中,则必须有4个活动线程,并且由于队列已满,将引发异常;

3.2. 如果task5在队列中,则必须有三个线程处于活动状态,因此将创建thread4并运行task6;

3.3. 如果队列为空,则将task6放入队列中。

在条件3.1下,可以抛出异常。但是在测试中,任务会很快从块队列中取出,所以这种情况很少发生。

附笔。:

当maxSize=3且queueSize=1时,添加此行

<代码>线程。睡眠(10)

之后

<代码>用于(int i=0;i

可以使您的代码在没有异常的情况下运行。

 类似资料:

相关问答

相关文章

相关阅读