美文网首页
「Android 学习计划」之线程池

「Android 学习计划」之线程池

作者: 13kmsteady | 来源:发表于2018-05-24 18:33 被阅读46次

    前言

    由于 Android 系统不能在 UI 线程进行耗时的操作,通常我们会在子线程处理耗时操作。简单的写法就是就是 new Thread.start() 去执行耗时操作,但是频繁的创建线程势必会带来性能上的开销,接下来引入今天的主题:线程池

    首先来谈下线程池的优点:

    1. 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。

    2. 能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。

    3. 能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能。

    执行者 ThreadPoolExecutor

    Java 中线程池的真正实现为 ThreadPoolExecutor,该类的构造方法提供了一些列参数,可以配置不同的线程池。

     public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory)
    
    • corePoolSize: 线程池的核心线程数大小

    • maximumPoolSize:线程池允许创建的最大线程数

    • keepAliveTime:非核心线程闲置时的超时时长,超过这个时长,非核心线程就会被回收

    • unit:指定 keepAliveTime 参数的时间单位

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

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

    ThreadPoolExecutor 执行流程

    1. 首先线程池会判断核心线程是否已满?

      是:进入下个流程

      否:创建一个核心线程执行任务

    2. 判断任务队列是否已满?

      是:进入下个流程

      否:将任务加入任务队列,等候执行

    3. 判断线程数量是否到达最大线程数?

      是:执行饱和策略

      否:创建非核心线程执行任务

    线程池执行流程.png

    Android 中常见的线程池

    • FixedThreadPool

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

      线程数量固定的线程池。线程处于空闲状态时,并不会被回收,除非线程池被关闭了。

      当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来。

      只拥有核心线程,并且核心线程不会被回收。能更加快速的响应外界的请求。

      核心线程没有超时机制,任务队列没有大小限制。

    • CachedThreadPool

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

      线程数量不定的线程池,只有非核心线程,最大线程数可以任意大。

      线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新任务。否则就会利用空闲线程来处理新任务。

      线程池中的空闲线程都有超时机制,时长为 60 秒,超过 60 秒闲置线程就会被回收。

      任务队列是一个空集合,任何任务都会被立即执行。

      适合执行大量的耗时较少的任务。当整个线程池都处于闲置状态时,线程池中的线程都会超时而被停止。

    • SchedulerThreadPool

      public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
          return new ScheduledThreadPoolExecutor(corePoolSize);
      }
      
      public ScheduledThreadPoolExecutor(int corePoolSize) {
          super(corePoolSize, Integer.MAX_VALUE,
                DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
                new DelayedWorkQueue());
      }
      

      核心线程数量是固定的,非核心线程数是没有限制的。非核心线程闲置时会被立即回收。

      用于执行定时任务和具有固定周期的重复任务。

    • SingleThreadExecutor

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

      线程池内部只有一个核心线程,确保所有的任务都在同一个线程中按顺序执行。统一所有的外界任务到一个线程中,使得在这些任务直接不需要处理线程同步的问题。

    相关文章

      网友评论

          本文标题:「Android 学习计划」之线程池

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