Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确使用Java Executor?_Java_Multithreading_Executorservice_Java.util.concurrent_Threadpoolexecutor - Fatal编程技术网

如何正确使用Java Executor?

如何正确使用Java Executor?,java,multithreading,executorservice,java.util.concurrent,threadpoolexecutor,Java,Multithreading,Executorservice,Java.util.concurrent,Threadpoolexecutor,我在我的多线程应用程序中使用过Java Executor,但我似乎不知道什么时候最好使用以下每种方法: 一, 二, int Page_Count=200; ExecutorService executor=Executors.newFixedThreadPool(50); doneSignal=新的倒计时锁存器(页数); 对于(int i=0;i ExecutorService executor=Executors.newFixedThreadPool(50); 它简单易用。它隐藏了Threa

我在我的多线程应用程序中使用过Java Executor,但我似乎不知道什么时候最好使用以下每种方法:

一,

二,

int Page_Count=200;
ExecutorService executor=Executors.newFixedThreadPool(50);
doneSignal=新的倒计时锁存器(页数);
对于(int i=0;i
  • ExecutorService executor=Executors.newFixedThreadPool(50);

    它简单易用。它隐藏了
    ThreadPoolExecutor
    的低级细节

    可调用/可运行的
    任务数量较少,并且在无限队列中堆积任务不会增加内存并降低系统性能时,最好使用此选项。如果您有
    CPU/内存
    约束,请使用
    ThreadPoolExecutor
    和容量约束&
    RejectedExecutionHandler
    处理任务的拒绝

  • 您已使用给定计数初始化了
    CountDownLatch
    。此计数通过调用
    countDown()
    方法递减。我假设您稍后在可运行任务中调用递减。等待此计数达到零的线程可以调用
    await()
    方法之一。调用
    await()
    阻塞线程,直到计数为零。此类允许java线程等待其他线程组完成其任务

    用例:

  • 实现最大并行性:有时我们希望同时启动多个线程以实现最大并行性

  • 等待N个线程完成后再开始执行

  • 死锁检测

    更多细节请看Lokesh Gupta的文章

  • :它提供了更多的控制来微调各种线程池参数。如果应用程序受活动
    可运行/可调用
    任务数量的限制,则应通过设置最大容量来使用有界队列。一旦队列达到最大容量,就可以定义RejectionHandler。Java提供了四种类型的
    RejectedExecutionHandler

  • 在默认的
    ThreadPoolExecutor.AbortPolicy
    中,处理程序在拒绝时抛出运行时拒绝执行异常

  • ThreadPoolExecutor.CallerRunPolicy
    中,调用execute自身的线程运行任务。这提供了一种简单的反馈控制机制,可以降低提交新任务的速度

  • ThreadPoolExecutor.DiscardPolicy
    中,无法执行的任务被简单地丢弃

  • ThreadPoolExecutor.DiscardOldestPolicy
    中,如果未关闭执行器,将丢弃工作队列头部的任务,然后重试执行(可能再次失败,导致重复执行)

    如果您想模拟
    CountDownLatch
    行为,可以使用
    invokeAll()
    方法

  • 您没有引用的另一个机制是

    ForkJoinPool
    是在Java7中添加到Java中的 Java
    ExecutorService
    ,但有一个区别。
    ForkJoinPool
    实现了它 任务很容易将其工作分成更小的任务,然后 也已提交到
    ForkJoinPool
    中。当空闲工作线程从繁忙工作线程队列中窃取任务时,任务窃取会在
    ForkJoinPool
    中发生

    Java 8在中又引入了一个API来创建工作窃取池。您不必创建
    RecursiveTask
    RecursiveAction
    ,但仍然可以使用
    ForkJoinPool

      public static ExecutorService newWorkStealingPool()
    
    使用所有可用的处理器作为其目标并行级别创建工作线程池

    默认情况下,它将以CPU核心数作为参数

  • 所有这四种机制都是相辅相成的。根据您想要控制的粒度级别,您必须选择正确的机制

    int Page_Count=200;
    ExecutorService executor=Executors.newFixedThreadPool(50);
    doneSignal=new CountDownLatch(Page_Count);
    for (int i=0;i<Page_Count;i++) executor.execute(new A_Runner(doneSignal, ... some parameter ...));
    doneSignal.await();
    executor.shutdown();
    while (!executor.isTerminated()) { Thread.sleep(100); }
    
    int Executor_Count=30;
    ThreadPoolExecutor executor=new ThreadPoolExecutor(Executor_Count,Executor_Count*2,1,TimeUnit.SECONDS,new LinkedBlockingQueue());
    List<Future<String>> futures=new ArrayList<>(3330);
    
    for (int i=0;i<50;i++) futures.add(executor.submit(new A_Runner(... some parameter ...));
    executor.shutdown();
    while (!executor.isTerminated()) { executor.awaitTermination(1,TimeUnit.SECONDS); }
    for (Future<String> future : futures)
    {
        String f=future.get();
        // ...
    }
    
      public static ExecutorService newWorkStealingPool()