操作系统中线程是系统调度的最小单元同时线程也是一种受限的系统资源,线程不可能无限制产生,并且线程的创建和销毁都会有相应的开销,当系统中存在大量的线程时,系统会通过时间片轮训的方式调度每个线程,因此线程不可能做到绝对的并行,一个进程中不可能频繁的创建和销毁线程,这样做是不高效的,因此采用线程池的方式,线程池会缓存一定数量的线程,通过线程池就可以避免因为频繁创建和销毁线程所带来的系统开销。
主线程是指进程所拥有的线程,默认情况下一个进程只有一个线程,这个线程就是主线程,主线程用来处理和界面交互相关逻辑。子线程也叫作工作线程,除了主线程之外的都是子线程。
Android中的主线程主要作用是运行四大组件以及处理他们和用户的交互,而子线程的作用是执行耗时任务。
Android中的线程:AsyncTask、HandlerThread、以及IntentService。
AsyncTask在线程池中执行后台任务,然后把执行的进度和结果传递给主线程并在主线程中更新UI。
四个主要的方法:
onPreExecute:主线程中执行,异步任务开始之前执行,做一些准备工作
doInBancGround:在线程池中执行,用于执行异步任务
onProgressUpdate:在主线程中执行,当后台任务进度发生改变时此方法会被调用。
onPostExecute:在主线程中执行
AsyncTask具体使用过程中的一些条件限制
1.AsyncTask的类必须在主线程中加载。(ActivityThread的main方法中调用了AsyncTask的init方法)
2.AsyncTask的对象必须自主线程中创建
3.execute方法必须在主线程中调用
4.一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会出现运行时异常。
AsyncTask内部有一个静态的InternalHandler对象,该对象继承与Handler,用于将执行结果从子线程切换到主线程,因此该Handler要求在主线程中创建。由于静态类成员会在类加载的时候创建,因此这就要求他的外部类AsyncTask在主线程中加载,否则同一个进程中的AsyncTask就无法进行正常工作。
HandlerThread继承与Thread,是一种可以使用Handler的Thread,实现原理:在run方法中通过Looper.prepare来创建消息队列,并通过Looper.loop来开启消息循环。这样就可以在Handler中创建Handler了
IntentService是一种特殊的Service,他继承了Service并且自己是一个抽象类,因此必须创建他的子类才能使用IntentService。IntentService用于执行后台耗时的任务,当任务执行后会自动停止,同时由于IntentService是服务的原因,它的优先级比单纯的线程要高很多(不容易被系统杀死),所以IntentService比较适合执行一些高优先级的后台任务。
在IntentService的onCreate方法中会创建HandlerThread相关的一些东西并获取到与之对应的Handler,然后在onStart方法中将接收到的Intent通过Handler发送,该Handler接收到消息后(消息循环机制),会将Intent对象传递给onHandleIntent方法,然后皆可以通过不同的Intent对不同的后台任务进行执行,当onHandleIntent方法执行结束后,IntentService会调用stopSelf(有个id,保证所有消息执行完才终止)方法尝试终止服务。
线程池带来的好处:
1.重用线程池中的线程,避免因为线程的创建和开销带来的性能影响
2.能够有效控制线程池的最大并发数,避免大量的线程之间因为互相抢占系统资源而导致阻塞现象
3.能够有效的对线程进行管理,并提供定时执行以及指定间隔循环执行等功能。
Android中的线程池来源于Executor,他是一个接口,真正的线程池的实现为ThreadPoolExecutor
ThreadPoolExecutor构造方法的几个参数:
1.corePoolSize:核心线程数
2.maximumPoolSize:线程池所容纳的最大线程数
3.keepAliveTime:非核心线程闲置时的超时时长
4.workQueue:存储通过线程池的execute方法提交的Runnable对象。
ThreadPoolExecutor执行任务所遵循的原则:
1.如果线程池中的线程数量未达到核心线程的数量没那么会直接启动一个核心线程来执行任务
2.如果线程中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等候执行
3.如果步骤2中无法将任务插入到任务队列中,这说明任务队列已满这个时候如果线程池数量未达到线程池规定的最大数,那么会立刻启动一个非核心线程来执行任务
4.如果步骤3中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用rejectExecutionHandler的rejectExecution方法通知调用者。
线程池分为四类:
FixedThreadPool:线程数量固定的线程池:该线程池中只有核心线程并且即使线程处于空闲状态时,也不会被回收,优先级比较高,能够快速响应外界请求,并且没有超时闲置,任务队列大小也没有限制。比较适用于对响应速度较高的请求
CachedThreadPool:线程数量不定的线程池,只拥有非核心线程,并且线程最大数为Integer.MAX_VALUE;并且设有超时机制(60),超时60秒闲置会被回收。比较适用于大量的耗时少的任务
ScheduledThreadPool:核心线程数固定,非核心线程数不固定,并且当非核心线程闲置时会被立即回收,,适用于执行定时任务和具有固定周期的任务。
SingleThreadExecutor:内部只有一个核心线程,确保所有的任务都在同一个线程中执行。
因篇幅问题不能全部显示,请点此查看更多更全内容