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

SynchronousQueue in ThreadPoolExecutor
EN

Stack Overflow用户
提问于 2017-12-05 09:35:37
回答 1查看 5.6K关注 0票数 8

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

Java程序:

代码语言:javascript
复制
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();
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-07 08:57:45

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

代码语言:javascript
复制
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并创建新线程。
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47650247

复制
相关文章

相似问题

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