线程池

作者: allsunny | 来源:发表于2022-06-22 15:14 被阅读0次

    线程池

    项目文件:HelloJava-ThreadPoolExecutorDemo

    1. 线程池优点:

      • 重用线程,避免创建和销毁线程的性能开销;
      • 有效控制线程池最大并发数,避免大量线程之间因互相抢占系统资源而导致的阻塞现象;
      • 能对线程进行简单管理,并提供定时执行已经间隔循环执行等功能;
    2. 继承关系:源于Executor;真正实现是ThreadPoolExecotor;

      public interface Executor {
          void execute(Runnable command);
      }
      public interface ExecutorService extends Executor {...}
      public abstract class AbstractExecutorService implements ExecutorService {...}
      public class ThreadPoolExecutor extends AbstractExecutorService {...}
      
    3. ThreadPoolExecutor

      public ThreadPoolExecutor(int corePoolSize,
                                int maximumPoolSize,
                                long keepAliveTime,
                                TimeUnit unit,
                                BlockingQueue<Runnable> workQueue
                                ThreadFactory threadFactory
                                RejectedExecutionHandler handler){
          ...
          private volatile boolean allowCoreThreadTimeOut;
          ...
      }
      
      • corePoolSize:核心线程数,核心线程会在线程池中一直存活。如果allowCoreThreadTimeOut为true,闲置的核心线程等待时长超过keepAliveTIme所指定的时长,核心线程会被终止;

      • maximumPoolSize:线程池所能容纳的最大线程数;

      • keepAliveTime非核心线程闲置的超时时长,超过时长,非核心线程被回收;如果allowCoreThreadTimeOut为true,同样作用于核心线程;

      • unit: keepAliveTime参数的时间单位,枚举值,常用TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS、TimeUnit.MINUTES;

      • workQueue:任务队列,通过线程execute方法提交的Runnable对象会存储在这个参数中;

      • threadFactory:线程工厂,为线程池提供创建新线程的功能。

        public interface ThreadFactory {
            Thread newThread(Runnable r);
        }
        
      • RejectedExecutionHandler handler:当线程池无法执行新任务,如任务队列已满或者无法成功执行任务,会调用handler.rejectedExecution,默认抛出异常。

    4. ThreadPoolExecutor执行流程:

      • 先开核心线程
      • 填充任务队列
      • 任务队列满了但未达到maximumPoolSize,再开非核心线程
      • 线程池数量达到线程池规定的最大值maximumPoolSize,handler抛出异常;
    5. 线程池分类:

      • FixedThreadPool:线程数量固定,只有核心线程且不会被回收;任务队列没有大小限制;

         public static ExecutorService newFixedThreadPool(int nThreads) {
             return new ThreadPoolExecutor(nThreads, nThreads,
                                           0L, TimeUnit.MILLISECONDS,
                                           new LinkedBlockingQueue<Runnable>());
         }
        
      • CachedThreadPool:只有非核心线程,线程数量不定;超时60s回收;SynchronousQueue可以理解为无法存储元素的队列;适合执行大量的耗时少的任务,当线程池闲置时,线程都会被超时回收,几乎不占用系统资源;

        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
        
      • ScheduledThreadPool:核心线程固定,非核心线程没有限制,非核心线程闲置立即回收(keepAliveTime为0);主要执行定时任务周期任务;schedule:计划(表),进度表,调度。

        public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
            return new ScheduledThreadPoolExecutor(corePoolSize);
        }
        
        public ScheduledThreadPoolExecutor(int corePoolSize) {
            super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
                  new DelayedWorkQueue());
        }
        
      • SingleThreadPool只有一个核心线程;所有任务统一到一个线程,不需要处理线程同步问题。

        public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
        }
        
    6. 通过Executors来创建线程池;(非Executor)

      ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
      fixedThreadPool.execute(runnable);
      
      ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
      cachedThreadPool.execute(runnable);
      
      ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
      scheduledThreadPool.execute(runnable);
      
      ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
      singleThreadExecutor.execute(runnable);
      

    相关文章

      网友评论

          本文标题:线程池

          本文链接:https://www.haomeiwen.com/subject/bakuvrtx.html