线程池
为什么要使用线程池?
1,降低资源消耗,因为线程是很宝贵的资源,反复创建会降低系统的性能
2,提升系统的响应速度,通过复用线程,省去创建线程的过程,因此整体上提升了系统的响应速度。
3,提升线程的客观理性,直接创建线程无法统一进行管理,可以使用线程池进行统一调度。
线程池执行任务的过程:
线程池调度算法创建线程池的方法或者说线程池的种类很多,但是归根结底,都是调用了下面的这个构造方法。
该方法参数说明如下:
可以看到该类提供了四种丢弃策略,也可以继承RejectedExecutionHandler去自定义。
ececute()方法源码分析:
这里的ctl保存了线程池中的线程数以及线程池的状态:线程池的状态共有五种,因此用3位二进制表示。用其他29位表示线程池中的活着的线程数。从表示状态需要左移可以看出,ctl是用高三位表示线程池的状态,用低29位表示线程数。
如何获取线程池中的线程数,就相当于获取低29位代表的数字。
CAPACITY是对1左移29位,相当于1后面有29个0,再减1相当于有29个1。
0010 0000 0000 0000 0000 0000 0000 0000
-1:0001 1111 1111 1111 1111 1111 1111 1111
在workerCount中,直接用c与CAPACITY就是取c的低29位。在runStateOf中先是对CAPACITY取反,也就是 1110 0000 0000 0000 0000 0000 0000 0000,然后再与c进行与运算,得到的就是c的高三位。
ctlOf是将两个int的进行或运算,包装为ctl。
这个与读写锁中的同步状态记录读锁获取次数和写锁获取次数是一致的。
RejectedHandlerPolicy
AbortPolicy:直接抛出异常
CallerRunsPolicy:A handler for rejected tasks that runs the rejected task directly in the calling thread of the {@code execute} method, unless the executor has been shut down, in which case the task is discarded.
交给当前调用的线程执行DiscardPolicy:A handler for rejected tasks that silently discards the rejected task.
具体实现:
DiscardOldestPolicy:A handler for rejected tasks that discards the oldest unhandled
* request and then retries {@code execute}, unless the executor
* is shut down, in which case the task is discarded.
网友评论