首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ThreadPoolExecutor Java

ThreadPoolExecutor Java
EN

Stack Overflow用户
提问于 2017-07-24 07:12:54
回答 1查看 464关注 0票数 0

我有一个示例代码。

代码语言:javascript
复制
@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时,我得到了异常,因为线程池执行器不能插入一个任务到队列,当我设置queueSize 3是可以的。我不明白为什么当我设置maxSize = 4时,测试是可以的。这是文件上的。

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

回答 1

Stack Overflow用户

发布于 2017-11-28 15:30:47

实际上,当= 4时,可能会出现异常引发的

第一次打电话给passTask(coreSize, service),我们得到了task1,task2,task3。并将创建thread1、thread2、thread3来运行它们。

第二次调用passTask(coreSize, service)

  1. I= 0,我们得到task4,task4将被放到队列中。
  2. I= 1,我们得到task5。 2.1。如果task4仍在队列中,则将创建thread4并运行task5; 2.2。如果task4已被thread1、thread2或thread3从队列中取出,则task5将被放入队列中。
  3. I= 2,得到task6。 3.1。如果task4仍在队列中,则必须有4个活动线程,并且由于队列已满,将引发异常; 3.2。如果task5在队列中,则必须有三个线程处于活动状态,因此将创建thread4并运行task6; 3.3。如果队列为空,task6将被放入队列中。

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

P.S.:

当maxSize =3和queueSize =1时,添加以下行

Thread.sleep(10);

之后

for (int i=0; i < coreSize; i++) {

可以使您的代码毫无例外地运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45274318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档