1.如果将线程看做厨师做菜,那么厨师就可分为正式员工(core)和临时员工(tmp),正式员工与临时员工差距就在于正式员工一般情况下不能被解雇,而临时员工随时可能被解雇.
正式员工上限名额为 corePoolSize
临时员工上限名额为 maximumPoolSize - corePoolSize
若以生产者消费者模型分析,则顾客是生产者,提交任务到阻塞队列中,员工是消费者,从阻塞队列中取任务做任务,
2.ThreadPoolExecutor(按需创建的方式创建线程)
一开始是线程池没有任何线程,当随着任务提交时有以下几种情况:
(1) 正式员工数量没有达到上限时,添加正式员工;
(2) 正式员工数量达到上限时,先将任务放在阻塞队列中等待其他某个任务结束,再从阻塞队列中取出该任务执行;
(3) 当阻塞队列达到最大容量时(阻塞队列已满),雇佣临时员工;
(4) 当正式员工与临时员工人数都达到上限且阻塞队列已满时,执行拒绝策略.
3.四种拒绝策略
4.线程池代码演示
public static void main(String[] args) {
// 存放等候执行的任务
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(3);
// 线程工厂
ThreadFactory tf = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r,"正式员工");
return t;
}
};
ExecutorService service = new ThreadPoolExecutor(
3,//正式员工
3,//临时员工
5, TimeUnit.SECONDS,
queue,
tf,
new ThreadPoolExecutor.AbortPolicy() //拒接策略
);
Runnable task = new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(3650000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 10; i++) {
sc.nextLine();
service.execute(task);
}
}
当输入员工数上限后则抛出异常(该代码块只包含6个线程)
5.线程池概述
corePoolSize : 核心线程上限
maximumPoolSize : 全部线程上限
keepAlive + unit : 默认情况下 > corePoolSize 的线程的存活时间(没有任务时)
queue : 任务队列
rejectHandle : 拒绝(默认) , 调用者允许 , 丢弃最老的 , 丢弃当前 .
线程池按需创建线程 :
(1) 起初没有任何线程,随着任务提交,创建 core 线程,(当前线程 < corePoolSize);
(2) 优先提交队列,直到队列满;
(3) 创建 > corePoolSize 的线程,直到 maximumPoolSize
(4) 执行拒绝策略