首页 文章

使用LinkedBlockingQueue的ExecutorService与ThreadPoolExecutor

提问于
浏览
43

我正在开发一个多线程项目,我需要生成多个线程来测量我的客户端代码的端到端性能,因为我正在进行负载和性能测试 . 所以我创建了以下使用 ExecutorService 的代码 .

以下是 ExecutorService 的代码:

public class MultithreadingExample {

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(20);
        for (int i = 0; i < 100; i++) {
            executor.submit(new NewTask());
        }

        executor.shutdown();
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    }
}

class NewTask implements Runnable {

    @Override
    public void run() {
        //Measure the end to end latency of my client code
    }   
}

Problem statement:

现在我正在阅读互联网上的一些文章 . 我发现还有 ThreadPoolExecutor . 所以我很困惑我应该使用哪一个 .

如果我将以上代码替换为:

ExecutorService executor = Executors.newFixedThreadPool(20);
    for (int i = 0; i < 100; i++) {
        executor.submit(new NewTask());
    }

至:

BlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>();

ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, TimeUnit.MILLISECONDS, threadPool);

tpExecutor.prestartAllCoreThreads();

    for (int i = 0; i < 100; i++) {
        tpExecutor.execute(new NewTask());
    }

这会有什么不同吗?我试图了解使用 ExecutorService 的原始代码与使用 ThreadPoolExecutor 粘贴的新代码之间的区别 . 我的一些队友说第二个(ThreadPoolExecutor)是正确的使用方式 .

谁能为我澄清一下这个?

6 回答

  • 1

    这是 Executors.newFixedThreadPool 的来源:

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    

    如上所示,它在内部使用具有默认配置的 ThreadPoolExecutor 类 . 现在有些情况下默认配置不合适而不是 LinkedBlockingQueue 需要使用优先级队列等 . 在这种情况下,调用者可以通过实例化并将所需的配置传递给它来直接处理底层 ThreadPoolExecutor .

  • 11

    那那会有什么不同吗?

    这将使您的代码更复杂,几乎没有什么好处 .

    我试图了解使用ExecutorService的原始代码与使用ThreadPoolExectuor粘贴的新代码之间的区别是什么?

    几乎没有 . Executors 创建一个ThreadPoolExecutor来完成实际工作 .

    我的一些队友说第二个(ThreadPoolExecutor)是正确的使用方式?

    仅仅因为它更复杂并不意味着它是正确的做法 . 设计人员提供了Executors.newXxxx方法,使您的生活更简单,因为他们希望您使用这些方法 . 我建议你也使用它们 .

  • 4
    ExecutorService executor = Executors.newFixedThreadPool(20);
    

    基本上是

    return new ThreadPoolExecutor(20, 20,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    

    2 .

    BlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>();
    ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L,
        TimeUnit.MILLISECONDS, threadPool);
    

    在第二种情况下,您只是将maxPoolSize增加到2000,我怀疑您需要它 .

  • 2

    我相信RejectionHandler还有一个优势 . 纠正我,如果错了

  • 23

    在第一个示例中,您使用以下语句创建了仅20个线程

    ExecutorService executor = Executors.newFixedThreadPool(20);
    

    在第二个示例中,您已将线程限制范围设置在 20 to 2000 之间

    ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, 
                                         TimeUnit.MILLISECONDS,threadPool);
    

    更多线程可供处理 . 但是您已将任务队列配置为无界队列 .

    如果您定制了以下许多或所有参数,ThreadPoolExecutor会更有效 .

    ThreadPoolExecutor(int corePoolSize, 
                   int maximumPoolSize, 
                   long keepAliveTime, 
                   TimeUnit unit, 
                   BlockingQueue<Runnable> workQueue, 
                   ThreadFactory threadFactory,
                   RejectedExecutionHandler handler)
    

    设置 max capacity for workQueue 时, RejectedExecutionHandler 会很有用,并且已提交给Executor的任务数超过 workQueue .

    有关详细信息,请查看ThreadPoolExecutor中的“已拒绝任务”部分 .

  • 66

    经过2天 GC out of memory exceptionThreadPoolExecutor 救了我的命 . :)

    正如巴拉吉所说,

    [..] RejectionHandler还有一个优势 .

    在我的情况下,我有很多 RejectedExecutionException 并指定(如下)丢弃政策解决了我所有的问题 .

    private ThreadPoolExecutor executor = new ThreadPoolExecutor(1, cpus, 1, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.DiscardPolicy());
    

    不过要小心!仅当您需要执行 all 提交给执行程序的线程时,它才有效 .

    有关 ThreadPoolExecutor 的更多信息,请查看Darren's answer

相关问题