Android 中的线程池

Android 中的四种线程池

在开发中使用线程池的优点

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

    开辟一块内存空间,存放许多未死亡的线程,池中线程执行调度有池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样就可以避免反复创建线程对象所带来的性能开销,节省了系统的资源

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

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

Android 中的线程池

Android 中的线程概念来源于 Java 中的 Executor ,Executor 是一个接口,其子接口是 ExecutorService,最终 ThreadPoolExecutor 实现了该接口并提供了一系列参数来配置线程池。

启动:调用线程池对象的 execute(Runnable r) 启动,Runnable 的 run 方法会运行在子线程,以及 ScheduleThreadPool 的 schedule 延迟执行,和 scheduleAtFixedRate 方法,延迟一段时间执行并每隔一段时间执行一次

停止:shutdown 不会立即停止,等待缓冲队列中的任务执行完成后停止,并不在接收新的任务
shutdownNow 立即终止,并打断正在执行的任务,清空缓冲队列,返回未执行的任务

ThreadPoolExcutor 的构造方法中的参数

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
  1. corePoolSize 线程池维护线程的最小数量,一般设置等于 CPU 核数 + 1,添加任务时,如果线程池中的数量小于 corePoolSize ,不管线程池中的线程是否处于空闲状态,都会创建新的线程来处理被添加的任务

  2. maximumPoolSize 线程池维护线程的最大数量,一般设置等于 CPU 核数的两倍再加 1 ,添加任务时,如果线程池中的数量等于 corePoolSize ,并且 workQueue 已满,会创建新的线程来处理被添加的任务

  3. keepAliveTime 设置非核心线程等待的超时时间 unit 超时时间单位的枚举表示,如果 allowCoreThreadTimeOut() 设置为 true ,则核心线程也会有超时时间,默认核心线程无超时时间

  4. workQueue 线程池所使用的缓冲队列,添加任务时,如果线程池中的数量等于 corePoolSize ,但是 workQueue 未满,那么任务被放入缓冲队列,一般设置为 128 ,超出时会调用相应的 Handler (并不是Android 中的Handler) 来处理,默认为抛出拒绝异常,RejectedExecutionHandler 抛出 rejectedExecution

  5. 缓冲队列的大小一般设置为 128 ,添加超出时会安装该线程池设置的处理方式处理,默认为抛出拒绝异常

  6. ThreadFactory 作用为为线程池创建 Thread

常用线程池的分类

通过 Executors 的一系列 new 静态方法获取不同类型的线程池

一、FixedThreadPool

  1. 是一种线程数固定的线程池,当线程处于空闲状态时,不会被回收,除非线程池关闭了。当所有的线程都处于活动状态时,新任务都会处于等待状态,知道有线程空闲出来。
  2. 只有核心线程没有非核心线程,优点是响应速度更快。
  3. 没有超时机制,任务队列也没有大小限制
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(),
                                  threadFactory);
}

二、CachedThreadPool

  1. 是一种现场数量不定的线程池,只有非核心线程,并且最大线程数量为 Integer.MAX_VALUE
  2. 当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理任务,否则会利用空闲线程来处理任务
  3. 线程池中的空闲线程都有超时机制,为60秒,超过60秒空闲的线程就会被回收
  4. 任务队列 SynchronousQueue 是无法插入任务的,说明所有任务都会被立即执行
  5. 适合执行大量的耗时较少的任务
  6. 当整个线程池都处于闲置状态时,线程池中的线程都会超时而被停止,这时候 CachedThreadPool 中实际是没有任何线程的,几乎不占任何系统资源
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}

三、ScheduledThreadPool

  1. 它的核心线程数量固定,非核心线程数量无限制
  2. 当非核心线程限制时立即回收
  3. 适合执行具有固定周期的重复任务
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

  1. 只有一个核心线程,确保所有任务都在同一线程中按顺序执行
  2. 意义在于同一所有的外界任务到一个线程中,这使得这些任务之间不需要处理线程同步问题
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • 线程池的优点: 重用线程池中的线程,避免因为线程的创建和销毁带来的性能消耗 能有效的控制线程的最大并发数,避免大量...
    乆丩乣阅读 5,376评论 5 30
  • 很久没有更新了,首先跟各位说声对不起。近段时间陷进了失眠的深渊难以自拔,工作、生活一团糟,每天都是满满的负能量,学...
    山野纸鹤阅读 1,055评论 0 9
  • 线程池的好处 (1)重用线程池中的线程,避免因为线程的创建和销毁所带来的性能的开销。(2)能有效控制线程池的最大并...
    蓝枫zeke阅读 349评论 0 2
  • 线程池的优点: 1.重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。 2.能有效控制线程池的最大并发...
    铜角大王阅读 126评论 0 0
  • 其实进入这个软件,是因为看了剽悍一只猫的微信公众号。没想到进来以后,发现写点东西原来这么简单,或许这就是我改变的一...
    麗姐阅读 285评论 0 0