一、前言
前一节介绍了线程池基本参数和概念,下面说下如何自定义线程池。
二、自定义线程池
1、步骤
(1)编写任务类(MyTask),实现Rubbalbe接口;
(2)编写线程类(MyWorker),用于执行任务,需要持有所有任务;
(3)编写线程池类(MyThreadPool),包含提交任务,执行任务的能力;
(4)编写测试类(MyTest),创建线程池对象,提交多个任务测试。
2、具体代码
2.1MyTask
package com.threadpoolexecutor.demo01;
/*
需求:
自定义线程练习,这是任务类,需要实现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) {
e.printStackTrace();
}
System.out.println("线程:" +name +"完成了任务:" +id);
}
@Override
public String toString() {
return "MyTask{" +
"id=" +id +
'}';
}
}
2.2MyWorker
package com.threadpoolexecutor.demo01;
import java.util.List;
/*
需求:
编写一个线程类,需要继承Thread类,设计一个属性,用于保存线程名字;
设计一个集合,用于保存所有的任务*/
public class MyWorker extends Thread{
//public class MyWorker implements Runnable{
// 保存线程的名字
private String name;
private Listtasks;
// 利用构造方法,给成员变量赋值
public MyWorker(String name,List tasks) {
super(name);
this.tasks = tasks;
}
@Override
public void run() {
// 判断集合中是否有任务,只要有,就一直执行
while (tasks.size() >0){
Runnable r =tasks.remove(0);
r.run();
}
}
}
2.3MyThreadPool
package com.threadpoolexecutor.demo01;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/*
这是自定义线程池类
成员变量: 1:任务列表 集合 需要控制线程安全问题 2:当前线程数量 3:核心线程数量 4:最大线程数量 5:任务队列的长度
成员方法: 1:提交任务:
将任务添加到集合中,需要判断是否超出了任务总长度 2:执行任务:
判断当前线程的数量,决定创建核心线程还是非核心线程*/
public class MyThreadPool {
// 1:任务队列 集合 需要控制线程安全问题
private Listtasks =Collections.synchronizedList(new LinkedList<>());
// 2:当前线程数量
private int num;
// 3:核心线程数量
private int corePoolSize;
// 4:最大线程数量
private int maxSize;
//5:任务队列的长度
private int workSize;
public MyThreadPool(int corePoolSize,int maxSize,int workSize) {
this.corePoolSize = corePoolSize;
this.maxSize = maxSize;
this.workSize = workSize;
}
// 1:提交任务
public void submit(Runnable r){
// 判断当前集合中任务数量,是否超出了最大任务数量
if (tasks.size() >=workSize){
System.out.println("任务:" + r +"被抛弃了...");
}else {
tasks.add(r);
// 执行任务
execTask(r);
}
}
// 2:执行任务
public void execTask(Runnable r){
// 判断当前线程池中的线程总数量,是否超出了核心数
if (num
new MyWorker("核心线程:" +num,tasks).start();
// new Thread(new MyWorker("核心线程:" + num, tasks)).start();
num ++;
}else if (num
new MyWorker("非核心线程:" +num,tasks).start();
// new Thread(new MyWorker("非核心线程:" + num, tasks)).start();
num ++;
}else {
System.out.println("任务:" + r +"被缓存了...");
}
}
}
2.4MyTest
package com.threadpoolexecutor.demo01;
public class MyTest {
public static void main(String[] args) {
MyThreadPool pool =new MyThreadPool(2,4 ,20);
for (int i =0; i <30; i++){
MyTask my =new MyTask(i);
pool.submit(my);
}
}
}
2.5运行结果
参考:网易云课堂-全面深入学习线程池