zoukankan      html  css  js  c++  java
  • Executor 如何使用?

    Executor 英文意思是执行者,可以看出它的作用是提交和执行任务接口,也可以理解为是线程池。

    Executor 有一个子接口 ExecutorService,ExecutorService 可以管理和终止任务的方法,可以追踪异步任务的进度的 Executor。

    Executors 是线程池的工厂类,提供静态工具方法。使用 Executors 可以方便地创建各种类型的线程池。但是由于 Executors 创建的线程池内部很多地方用到了无界任务队列,在高并发场景下,无界任务队列会接收过多的任务对象,导致 JVM 抛出OutOfMemoryError,整个 JVM 服务崩溃,影响严重。所以很多公司已经不建议使用 Executors 去创建线程。

    简单介绍下 Executors 的使用:

    newFixedThreadPool:创建定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
    newCachedThreadPool:创建可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制
    newScheduledThreadPool:创建定长线程池,可执行周期性的任务
    newSingleThreadExecutor:创建单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行
    newSingleThreadScheduledExecutor:创建单线程可执行周期性任务的线程池
    newWorkStealingPool:任务可窃取线程池,不保证执行顺序,当有空闲线程时会从其他任务队列窃取任务执行,适合任务耗时差异较大

    JDK 提供的线程池相关的工具类中,最核心的是 ThreadPoolExecutor。它最复杂的构造函数有 7 个参数:

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

    参数说明: 

    corePoolSize:线程池保有的最小线程数
    maximumPoolSize:线程池创建的最大线程数
    keepAliveTime:一个线程空闲了 keepAliveTime * unit 这么长时间,且线程池的线程数大于 corePoolSize ,那么这个空闲的线程就要被回收了
    unit:keepAliveTime 的时间单位
    workQueue:任务队列
    threadFactory:线程工厂对象,可以自定义如何创建线程,如给线程指定 name
    handler:自定义任务的拒绝策略。线程池中所有线程都在忙碌,且任务队列已满,线程池就会拒绝接收再提交的任务。handler 就是拒绝策略,包括 4 种(即 RejectedExecutionHandler 接口的 4个实现类)
        AbortPolicy:默认的拒绝策略,throws RejectedExecutionException
        CallerRunsPolicy:提交任务的线程自己去执行该任务
        DiscardPolicy:直接丢弃任务,不抛出任何异常
        DiscardOldestPolicy:丢弃最老的任务,加入新的任务

    使用示例:

    package constxiong.interview;
    
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    import java.util.concurrent.SynchronousQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 测试 ThreadPoolExecutor 创建线程池
     * @author ConstXiong
     */
    public class TestThreadPoolExecutor {
    
        public static void main(String[] args) {
            testSubmitTask();
        }
        
        /**
         * 测试使用 ThreadPoolExecutor 创建线程池,并向线程池提交任务
         */
        private static void testSubmitTask() {
            int corePoolSize = 1;//最小线程数
            int maximumPoolSize = 2;//最大线程数
            long keepAliveTime = 1000L;//1000个单位时间
            Executor exector = new ThreadPoolExecutor(corePoolSize, 
                    maximumPoolSize, 
                    keepAliveTime, 
                    TimeUnit.MILLISECONDS, 
                    new SynchronousQueue<Runnable>(),//可以修改队列:有界队列、无界队列、有优先级的队列 
                    Executors.defaultThreadFactory(),//线程工程对象,可以定义如何创建线程
                    new ThreadPoolExecutor.AbortPolicy()); //任务队列已满,线程池决绝策略
            for (int i = 0; i < 5; i++) {
                exector.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        }
        
    }


    原文链接
     


     

  • 相关阅读:
    【k8s】Volume-persistentVolumeReclaimPolicy
    【k8s】Volume-pv
    【k8s】Secret-生成环境变量
    【k8s】Volume-nfs
    【k8s】Volume-hostPath
    【k8s】Volume-emptyDir
    【k8s】Volume-downwardAPI
    【k8s】Volume-Secret
    【k8s】Volume-ConfigMap-file
    SQL SERVER 列转行
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/12143179.html
Copyright © 2011-2022 走看看