线程池用处:
1.复用线程,降低资源消耗。
2.提高响应速度。
3.提高线程可管理性。
下面是自己写的线程池demo
jdk中的线程池ThreadPoolExecutor讲解
参数讲解(面试必问):corePoolSize 是cpu核心线程数(不会被销毁),当任务数比较大的时候 核心线程处理不完任务就会进入Blocking(阻塞队列),当阻塞队列依然不够存放的时候就会重新开启新的线程数,最多总线程达到maximumPoolSize,当达到最大线程数依然处理不完,就会交给RejectedExecutionHandler(拒绝策略)处理,keepAliveTime是线程空闲多长时间后会被销毁(核心线程不在这个范围内),TimeUnit是时间单位一般是秒,threadFactory一般没什么用,主要是给线程命名,可以不关注。
RejectedExecutionHandler的四个实现类
当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)。
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
(具体讲解可参考这篇文章:拒绝策略)。
提交任务有execute(Runnable r) 跟submit(Runnable r)俩种方式,区别是后者有返回值前者没有。
阻塞队列:
阻塞插入方法:队列满,放元素被阻塞。
阻塞移除方法:队列空,拿元素被阻塞
常见BlockingQueue:1. ArrayBlockingQueue 2.LinkedBlockingQueue
(具体讲解可参考这篇文章:常见的阻塞队列)
阻塞队列方法的讲解(都是一一对应的):
1、add(E e)
在不违反容量限制的情况下,可立即将指定元素插入此队列,成功返回true,当无可用空间时候,返回IllegalStateException异常。
2、offer(E e)
在不违反容量限制的情况下,可立即将指定元素插入此队列,成功返回true,当无可用空间时候,返回false。
3、put(E e)
直接在队列中插入元素,当无可用空间时候,阻塞等待。
4、offer(E e, long time, timeunit unit)
将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false。
5、E take()
获取并移除队列头部的元素,无元素时候阻塞等待。
6、E poll( long time, timeunit unit)
获取并移除队列头部的元素,无元素时候阻塞等待指定时间。
线程池提交任务方式
1.submit() 有返回值 2.execute() 没有返回值
如何合理的配置线程池?(面试必问)
与任务的特性有关
cpu密集型(大量计算 机器上CPU同时运行的线程个数)
io密集型(数据读取传输 机器上CPU同时运行的线程个数*2)
混合型(拆分)
悲观锁、乐观锁定义)
volatite 易变的 只能保证可见性 不是原子性 (多读易写)
保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)
volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。
AysncTask源码分析
AysncTask源码分析)
双端队列是干嘛的 arrayDeque)
asynctask里面为啥需要使用双端队列)
(这俩个问题以后处理))
blog.csdn.net/itachi85/ar… 明天解决)