线程池是为多线程而生的,首先我们先聊聊线程
1 什么是线程
线程,程序执行流的最小执行单位 - thread。
2 线程的创建以及状态切换
start() run() -------sleep()---->blocked
new Thread------->Runnable------>Runing---wait()-------->blocked ------------notify-------->Runnable
<--yeld()-- ------join()-----> blocked
---------run over-->dead
按上图分析线程的基本运行:
1 新建Thread: 方式有三 ,这里只介绍两种 A: 继承Thread;B:实现Runnable接口。看过源码的其实都知道两者都是对Runnable接口的实现
2 Runnable:调用.start()方法,表示线程随时可以被cpu调度
3 Running:线程被cpu调度,处于运行中
4 blocked(阻塞状态)阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态
A: 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。
B:同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
C:其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态
3 多线程的场景以及应用
常见场景:tomact请求每个客户的请求都是独立的线程,ftp下载,异步处理
为什么要使用线程池呢?就我的理解有以下原因: A: 性能:线程的创建和销毁是比较耗费时间和内存的,尤其是频繁的创建和销毁 ;B:资源:巨量的任务过来,如果每来一个任务我们就创建一个线程,我们就会创建大量的无用线程浪费资源;C:控制:线程池来管理线程。
线程池的java实现:
主要的java类 ThreadPoolExecutor源码不看了 我截图给大家
这个是构造方法:corePoolSize:核心线程数量;maximumPoolSize:最大线程数;keepAliveTime:最大存活时间;unit:存活时间单位;workQueue:任务队列;ThreadFactory:线程工厂;rejectedExecution:任务拒绝
一句话描述: 线程池中核心线程一直不会回收,当任务进来--如果核心线程有空闲则核心线程跑任务,否则 判断当前线程数量是否大于maximumPoolSize,小于则创建线程去跑任务。否则放进workQueue任务对队列中,如果任务队列已满则按给定的拒绝策略rejectedExecution进行处理。如果非核心线程闲置时间超过keepAliveTime,则线程回收