《Android进阶之光》阅读笔记3

线程同步:

synchronized关键字:防止多个线程同时执行

volatile关键字:共享变量被修饰说明线程修改了变量的值时,新的值对其他线程是立即可见的

        使用条件:1. 对变量的写操作不会依赖当前值

                          2. 该变量没有包含在其他变量的不变式中

一个语句中含有多个操作时,就不是原子操作(只有简单的读取赋值才是)

阻塞队列:

常用于生产者-消费者场景,生产者: 往队列添加元素的线程;消费者:往队列取出元素的线程

常见阻塞场景,支持的即为阻塞队列:

        1. 队列没有数据时,消费者端所有线程都被自动阻塞,直到有数据放入队列

        2. 队列数据未满时,生产者端的所有数据都会被自动阻塞,直到队列中有空的位置

阻塞队列核心方法:

放入:

offer(object)--将object加入阻塞队列,如果可以加返回true,否则返回false(不阻塞当前方法的线程)

offer(E o, long timeout, TimeUnit unit)--设定等待时间,在指定时间还不能往队列中加的话反悔失败

put(object) -- 将object加入队列中,如果没有空间则调用此方法的线程被阻断,直到有空间才继续

获取:

poll(long timeout, TimeUnit unit)-- 取出队列中队首元素,能取则立即返回,否则如果时间超时还没有就返回失败

take()--取出队列队首元素,如果为空则进入等待状态直到不为空

drainTo()--一次性从队列中获取所有可用数据对象,无需多次分批加锁或者释放锁

Java的7个阻塞队列:

ArrayBlockingQueue: 数组结构组成的有界阻塞队列,不保证线程公平:即先阻塞的生产者可以先往队列插入元素,先阻塞的消费者可以先从队列中获取元素

LinkedArrayBlockingQueue:链表结构组成的有界阻塞队列,生产者往队列放入数据时,队列会从生产者手中获取,只有当队列缓冲区达到最大值时才会阻塞生产者队列,直到消费者从队列中消费掉一个数据生产者线程才重新工作。优点:能够高效处理并发数据

PriorityBlockingQueue:支持优先级排序的无界阻塞队列,默认按照升序排列,可以自定义排序规则

DelayQueue:支持延时获取元素的无界阻塞队列,可以指定元素到期时间,只有到期时才能从队列中取走

SynchronizedQueue:不存储元素的阻塞队列,队列内部没有元素

LinkedTransferQueue:由链表组成的无界阻塞队列

LinkedBlockingQueue:由链表组成的双向阻塞队列,多了addFirst, addLast, offerFirst, offerLast等方法

线程池:

corePoolSize: 核心线程数

maxPoolSize: 最大线程数,超出的话会创建新的线程

keepAliveTime: 非核心线程闲置的超时时间,超过此事件,非核心线程会被回收,如果设置allowCoreThreadTimeOut为true,keepAliveTime也会应用到核心线程上

TimeUnit: keepAliveTime的时间单位,可选为DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS.

workQueue: 当前线程数大于corePoolSize,则将此任务添加到任务队列中

threadFactory: 线程工厂,一般情况下无须设置参数

RejectedExecutionHandler: 饱和策略,任务队列和线程池都满了则默认无法处理新任务并抛出异常

线程池允许创建的最大线程数为128,非核心线程空闲等待新任务的最长时间为1s

线程池的处理流程:

        1. 线程先判断线程数是否达到核心线程数,如果未达到则创建核心线程处理任务。

        2. 接着线程池判断任务队列是否已经满了,如果没有将任务添加到任务队列中。

        3. 任务队列已满,线程池判断线程数是否达到了最大线程数,如果没有则创建非核心线程处理任务,否则执行饱和策略

线程池的种类:

1. FixedThreadPool: 只有核心线程,并且数量是固定的

2. CachedThreadPool: corePoolSize=0, maxPoolSize=Integer.MAX_VALUE,需要创建线程的线程池,没有核心线程,比较适用于大量的需要立即处理且耗时较少的任务

3. SingleThreadExecutor: corePoolSize=maxPoolSize=1,能确保所有任务在一个线程中按照顺序依次执行

4.ScheduledThreadPool: 定时和周期性任务的线程池,corePoolSize为固定数值,maxPoolSize参数无效

AsyncTask的原理:

背景:多个任务更新UI的时候会显得代码臃肿,AsyncTask使得异步任务变得很简单

特点:为抽象的泛型类

public abstract class AsyncTask<Params, Progress, Result>{
    ...
}

Params: 参数类型;Progress: 后台任务执行进度类型;Result: 返回结果类型

4个核心方法:

        1. onPreExecute(): 主线程中执行,一般为任务执行前的准备工作

        2. doInBackground(Params): 一般用来执行较为耗时的操作,过程中可以调用publishProgress()来更新进度条

        3. onProgressUpdate(Progress): 在主线程中执行,调用publishProgress时会将进度更新在UI上

        4. onPostExecute(Result): 后台任务执行完毕的收尾工作,如更新UI和数据等

猜你喜欢

转载自blog.csdn.net/LYFly0016/article/details/131359470
今日推荐