android中线程池,Android中的线程和线程池

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

转载请注明原作者,如果觉得有用,心里夸我一句就好

Java中默认情况下一个进程只有一个线程,这个线程就是主线程,在Android中也叫做UI线程,主要负责四大组件以及它们和用户的交互逻辑,不能执行耗时的操作。网络请求,I/O等耗时操作需要在子线程中处理。

1. ThreadLocal

首先介绍一下浅析Android消息机制文章中提到的用于存储线程内部数据的ThreadLocal类,通过ThreadLocal类可以在指定的线程中存储数据,并且数据在存储以后只有在指定的线程中才可以获取到存储的数据,对于其它线程来说则无法获取到数据。因为ThreadLocal存储数据是与线程关联到一起的,所以一般来说,当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候就可以采用ThreadLocal。

2. 线程池的优点

相对于线程而言,线程池主要有以下优点:重用线程池中已经创建好的线程可以避免因为线程的创建和销毁所带来的性能开销

避免大量的线程之间因为互相抢占系统资源而导致的阻塞甚至死锁的现象

能够对线程进行简单的管理,提供定时或者间隔循环执行线程的功能

3. 线程池的实现

Android线程池的概念来源于Java中的Executor,Executor是一个接口,真正线程池的实现为ThreadPoolExecutor,它提供了一系列的参数来配置线程池。Android中不同类别的线程池也是直接或者间接配置ThreadPoolExecutor的参数来实现的。

从功能上来说Android的线程池主要分为四类,这四类线程池可以通过Executors所提供的工厂方法来得到,稍后会具体介绍这四类线程池。

4. ThreadPoolExecutor

下面这段代码是ThreadPoolExecutor类中常用的构造方法:public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory)corePoolSize

线程池的核心线程数,默认情况下核心线程会在线程池中一直存活,即使处于闲置状态。但是如果将ThreadPoolExecutor中允许设置核心线程超时时间的标示位allowCoreThreadTimeOut设为true的话,那么在线程闲置时间超过keepAliveTime所设定的时间后,核心线程就会被回收。

maximumPoolSize

线程池所能容纳的最大线程数,当活动线程达到这个数值后,后面新的任务会被阻塞。

keepAliveTime

设置线程池中线程的超时时间,当线程(核心线程和非核心线程)闲置时间超过所设定的时间后会被回收。这里需要注意的是核心线程之后在allowCoreThreadTimeOut设为true的时候超时机制才会对其生效。

unit

超时时间所使用的计量单位。

workQueue

线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会被存储到这个队列里。

threadFactory

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

5. 线程池执行任务遵循的大致规则

当新的任务到来的时候如果线程池中线程数量未达到核心线程数量的最大值,直接开启一个新的核心线程来执行任务;

如果线程池中线程数量已经达到或者超过了corePoolSize,任务会被插入到当前的任务队列中排队等待执行,如果队列已满无法插入并且线程池中的线程数量未达到最大值,那么开启一个非核心线程来执行任务;

如果线程的数量已经达到了maximumPoolSize,那么会抛出一个拒绝执行任务的异常。

6. Android中常见的线程池

可以根据在第四小节中介绍的ThreadPoolExecutor构造方法中各个参数的作用,来具体分析不同线程池所具备的不同功能。

6.1 FixedThreadPoolpublic static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue(),

threadFactory);

}

FixedThreadPool是一种线程数量固定的线程池,线程数量在实例化对象的时候传入,线程处于空闲状态的时候也不会被回收,除非线程池被关闭了;所有的线程都处于活动状态的时候新任务会处于等待状态,只有核心线程并且不会被回收(核心线程数量和最大数量相同,并且超时时间为0)意味着能够快速响应外界的请求。

6.2 newCachedThreadPoolpublic static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

数量不定的线程池,只有非核心线程,最大线程数为Integer.MAX_VALUE(所以相当于最大线程数可以任意大),线程的超时时间为60秒。当所有线程处于活动状态时,会创建新的线程处理到来的任务,否则会使用空闲线程,适合执行大量的耗时较少的任务。

6.3 newCachedThreadPoolpublic static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {

return new ScheduledThreadPoolExecutor(corePoolSize);

}

private static final long DEFAULT_KEEPALIVE_MILLIS = 10L;

public ScheduledThreadPoolExecutor(int corePoolSize) {

super(corePoolSize, Integer.MAX_VALUE,

DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,

new DelayedWorkQueue());

}

核心线程固定,非核心线程无限制(Integer.MAX_VALUE),非核心线程闲置之后会被立刻回收(默认的线程超时时间是10毫秒),主要用于执行定时或者具有固定周期重复执行的任务。

6.4 newSingleThreadExecutorpublic static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue(),

threadFactory));

}

只有一个核心线程确保所有的任务都按照顺序在同一线程中执行,使得任务之间不需要处理同步的问题。

参考资料

Android开发艺术探索

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值