ThreadPoolExecutor部分源码
构造方法:
public ThreadPoolExecutor(int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//最大空闲时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue//任务队列
RejectedExecutionHandler handler//饱和处理机制
) {
}
线程池设计:
- 核心线程数:银行正式员工数量
例如执行一个任务需要0.1秒,系统百分之八十的时间一秒钟生产100个任务,那么想要在1秒钟处理完所有任务需要十个线程,因此核心线程数是10; - 任务队列:银行大厅座位
核心线程数/单个任务执行时间*2 - 最大线程数:核心线程数加上不得不添加的线程数(临时工)
最大线程数 = (最大任务数-任务队列长度)*单个任务执行时间(最大任务数:系统每秒生产任务量) - 最大空闲时间:当银行没有办业务的人超过指定时间临时工下班(线程被销毁)
合理即可 - 饱和处理机制:当超过银行所能接待人数启用饱和处理机制
线程池原理:
自定义线程池——实现步骤
- 编写任务类(MyTask)继承Runnable接口
package com.itheima.Demo1;
/*
需求:
自定义线程练习,这是任务类需要实现Runnable;
包含任务编号,每一个任务啊执行0.2秒
*/
public class MyTask implements Runnable{
private int id;
//由于run方法是重写接口中的方法,因此id这个属性的初始化可以利用构造方法完成
public MyTask(int id) {
this.id = id;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println("线程:"+name+"即将执行任务:"+id);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("线程:"+name+"完成了任务:"+id);
}
@Override
public String toString() {
return "MyTask{" +
"id=" + id +
'}';
}
}
- 编写线程类(MyWorker),用于执行任务,需要持有所有任务
package com.itheima.Demo1;
import java.util.List;
/*
需求:
编写一个线程类,需要继承Thread类,设计一个属性,用于报讯线程的名字
设计一个集合,用于保存所有的任务;
*/
public class MyWorker extends Thread{
private String name;//保存线程的名字
private List<Runnable> tasks;
//利用构造方法,给成员变量赋值
public MyWorker(String name,List<Runnable> tasks) {
this.name = name;
this.tasks = tasks;
}
@Override
public void run() {
//判断集合中是否有任务,只要有,就一直执行任务
while (tasks.size()>0){
Runnable r = tasks.remove(0);
r.run();
}
}
}
- 编写线程池类(MyThreadPool),包含提交任务,测试任务的能力
package com.itheima.Demo1;
import java.util.*;
/*
自定义的线程池类:
成员变量
1:任务队列 集合
2:当前线程数量
3:核心线程数量
4:最大线程数量
5:任务队列长度v
成员方法:
1:提交任务
将任务添加到集合中,需要判断是否超出了任务总长度
2:执行任务
判断当前线程的数量,决定创建核心线程还是非核心线程
*/
public class MyThreadPool {
//任务队列
private List<Runnable> tasks = Collections.synchronizedList(new LinkedList<>());
//当前线程数量
private int num;
//核心线程数量
private int corePoolSize;
//最大线程数量
private int maxSize;
//任务队列的长度
private int workSize;
public MyThreadPool(int corePoolSize, int maxSize, int workSize) {
this.corePoolSize = corePoolSize;
this.maxSize = maxSize;
this.workSize = workSize;
}
//提交任务
public void submit(Runnable r){
//判断任务数量是否超出最大任务数
if(tasks.size()>=workSize){
System.out.println("任务:"+ r +"被丢弃了...");
}else {
tasks.add(r);
//执行任务
execTask(r);
}
}
//执行任务
private void execTask(Runnable r) {
//判断当前线程池中的线程总数量,是否超i出了核心数
if(num<corePoolSize){
new MyWorker("核心线程:"+num,tasks).start();
num++;
}else if(num<maxSize)
{
new MyWorker("非核心线程:"+num,tasks).start();
num++;
}else{
System.out.println("任务:"+r+"被缓存了...");
}
}
}
- 编写测试类(MyTest)
package com.itheima.Demo1;
public class MyTest {
public static void main(String[] args) {
//创建线程池类对象
MyThreadPool pool = new MyThreadPool(2,4,20);
//提交多个任务
for (int i = 0;i<30;i++){
MyTask myTask = new MyTask(i);
pool.submit(myTask);
}
}
}