如何正确使用Java Executor?
我在我的多线程应用程序中使用过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
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中的
JavaExecutorService
,但有一个区别。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()