• Java 线程池详解


    原文请参考:https://blog.csdn.net/fwt336/article/details/81530581

    1.ExecutorService的创建方式
    
        public ThreadPoolExecutor(int corePoolSize,
                                      int maximumPoolSize,
                                      long keepAliveTime,
                                      TimeUnit unit,
                                      BlockingQueue<Runnable> workQueue,
                                      ThreadFactory threadFactory,
                                      RejectedExecutionHandler handler)
    
    所有线程池最终都是通过这个方法来创建的。
    
    corePoolSize : 核心线程数,一旦创建将不会再释放。如果创建的线程数还没有达到指定的核心线程数量,将会继续创建新的核心线程,直到达到最大核心线程数后,核心线程数将不在增加;如果没有空闲的核心线程,同时又未达到最大线程数,则将继续创建非核心线程;如果核心线程数等于最大线程数,则当核心线程都处于激活状态时,任务将被挂起,等待空闲线程来执行。
    
    maximumPoolSize : 最大线程数,允许创建的最大线程数量。如果最大线程数等于核心线程数,则无法创建非核心线程;如果非核心线程处于空闲时,超过设置的空闲时间,则将被回收,释放占用的资源。
    
    keepAliveTime : 也就是当线程空闲时,所允许保存的最大时间,超过这个时间,线程将被释放销毁,但只针对于非核心线程。
    
    unit : 时间单位,TimeUnit.SECONDS等。
    
    workQueue : 任务队列,存储暂时无法执行的任务,等待空闲线程来执行任务。
    
    threadFactory :  线程工程,用于创建线程。
    
    handler : 当线程边界和队列容量已经达到最大时,用于处理阻塞时的程序
    

    2.线程池的类型

    2.1 可缓存线程池

    ExecutorService cachePool = Executors.newCachedThreadPool();

       看看它的具体创建方式:

    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
    

    通过它的创建方式可以知道,创建的都是非核心线程,而且最大线程数为Interge的最大值,空闲线程存活时间是1分钟。如果有大量耗时的任务,则不适该创建方式。它只适用于生命周期短的任务。

    2.2 单线程池

    ExecutorService singlePool = Executors.newSingleThreadExecutor();

    顾名思义,也就是创建一个核心线程:

    public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
        }
    

    只用一个线程来执行任务,保证任务按FIFO顺序一个个执行。

    2.3 固定线程数线程池

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

    也就是创建固定数量的可复用的线程数,来执行任务。当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行

    2.4 固定线程数,支持定时和周期性任务

    ExecutorService scheduledPool = Executors.newScheduledThreadPool(5);

    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }
    
    可用于替代handler.postDelay和Timer定时器等延时和周期性任务。
    
        public ScheduledFuture<?> schedule(Runnable command,
                                               long delay, TimeUnit unit);
    
        public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                          long initialDelay,
                                                          long period,
                                                          TimeUnit unit);
    
        public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                             long initialDelay,
                                                             long delay,
                                                             TimeUnit unit);
    scheduleAtFixedRate和sheduleWithFixedDelay有什么不同呢?
    
    scheduleAtFixedRate:创建并执行一个在给定初始延迟后的定期操作,也就是将在 initialDelay 后开始执行,然后在initialDelay+period 后下一个任务执行,接着在 initialDelay + 2 * period 后执行,依此类推 ,也就是只在第一次任务执行时有延时。
    
    sheduleWithFixedDelay:创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟,即总时间是(initialDelay +  period)*n

    2.4 手动创建线程池

    private ExecutorService pool = new ThreadPoolExecutor(3, 10,
                10L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(512), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
  • 相关阅读:
    [Go] Slices vs Array
    [置顶] SpecDD系列:“完成” 的定义
    关于游戏开发的一点随笔
    提高效率 常用的几个xcode快捷键
    关于android 自己实现 back键 home键
    (组合数学3.1.1.1)POJ 1146 ID Codes(字典序法)
    [置顶] c# asp.net 修改webconfig文件 配置
    python数据类型和3个重要函数
    jdk环境变量配置
    VM虚拟机下在LINUX上安装ORACLE 11G单实例数据库
  • 原文地址:https://www.cnblogs.com/lshan/p/10893703.html
Copyright © 2020-2023  润新知