【问题标题】:SynchronousQueue in ThreadPoolExecutorThreadPoolExecutor 中的 SynchronousQueue
【发布时间】:2017-12-05 09:35:37
【问题描述】:

我正在尝试了解ThreadPoolExecutor 中队列的行为。在下面的程序中,当我使用LinkedBlockingQueue 时,我一次只能向线程池提交一个任务。但是如果我将LinkedBlockingQueue 替换为SynchronousQueue,我可以立即将所有5 个任务提交到池中。在这种情况下,SynchronousQueueLinkedBlockingQueue 有何不同?

Java 程序:

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Sample {
    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingQueue<Runnable> threadPoolQueue = new LinkedBlockingQueue<>();
//      SynchronousQueue<Runnable> threadPoolQueue = new SynchronousQueue<>();
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, threadPoolQueue, threadFactory);
        Runnable np;

        for (int i = 1; i <= 5; i++) {
            np = new SampleWorker("ThreadPoolWorker " + i);
            tpe.submit(np);
        }

        System.out.println(tpe.getCorePoolSize());
        System.out.println(tpe.getPoolSize());
        System.out.println(tpe.getActiveCount());

        tpe.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        tpe.shutdown();
        System.out.println("Main task finished");
    }
}

class SampleWorker implements Runnable {
    private String workerName;

    SampleWorker(String tName) {
        workerName = tName;
    }

    @Override
    public void run() {
        try {
            for (int i = 1; i <= 10; i++) {
                Thread.sleep(3000);
                System.out.println(this.workerName);
            }
            System.out.println(this.workerName + " finished");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

【问题讨论】:

  • 看看this
  • @avix 这解释了SynchronousQueueLinkedBlockingQueue 之间的区别(大小为1)。但是在这里我没有为任何一个队列指定任何大小。使用LinkedBlockingQueue,我一次只能提交一个任务,而使用SynchronousQueue,我可以同时提交所有5个任务。在这两种情况下,我都将corePoolSize 设置为 0。 corePoolSize 不会影响 SynchronousQueue 吗?
  • @UnahD corePoolSize 不影响底层BlockingQueue,它控制ThreadPoolExecutor 的线程池大小,而不是BlockingQueue 大小。而且,正如文档所说,SynchronousQueue does not have any internal capacity, not even a capacity of onesize() always returns zero

标签: java multithreading threadpool threadpoolexecutor blockingqueue


【解决方案1】:

当您向ThreadPoolExecutor 提交任务时,它的工作方式如下:

if (numberOfWorkingThreads < corePoolSize) {
   startNewThreadAndRunTask();
} else if (workQueue.offer(task)) {
   if (numberOfWorkingThreads == 0) {
       startNewThreadAndRunTask();
   }
} else if (numberOfWorkingThreads < maxPoolSize)
    startNewThreadAndRunTask();
} else {
    rejectTask();
}
  • 当使用没有初始值的LinkedBlockingQueue时, workQueue.offer(task) 将永远成功,结果只有一个 线程已启动。
  • 调用SynchronousQueue.offer(task)时,只有在 另一个线程正在等待接收它。因为没有等待 线程,false 将被返回,并且每创建一个新线程 时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2021-04-26
    • 2017-01-11
    • 1970-01-01
    • 2013-12-08
    • 2016-07-08
    相关资源
    最近更新 更多