// 工作线程组
private WorkThread[] workThreads;
// 任务队列,作为一个缓冲
private final BlockingQueue taskQueue;
private final int worker_num;//用户在构造这个池,希望的启动的线程数
// 创建具有默认线程个数的线程池
public MyThreadPool() {
this(WORK_NUM,TASK_COUNT);
}
// 创建线程池,worker_num为线程池中工作线程的个数
public MyThreadPool(int worker_num,int taskCount) {
if (worker_num<=0) worker_num = WORK_NUM;
if(taskCount<=0) taskCount = TASK_COUNT;
this.worker_num = worker_num;
taskQueue = new ArrayBlockingQueue<>(taskCount);
workThreads = new WorkThread[worker_num];
for(int i=0;i<worker_num;i++) {
workThreads[i] = new WorkThread();
workThreads[i].start();
}
}
// 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器决定
public void execute(Runnable task) {
try {
taskQueue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁
public void destroy() {
// 工作线程停止工作,且置为null
System.out.println(“ready close pool…”);
for(int i=0;i<worker_num;i++) {
workThreads[i].stopWorker();
workThreads[i] = null;//help gc
}
taskQueue.clear();// 清空任务队列
}
// 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数
@Override
public String toString() {
return “WorkThread number:” + worker_num
- ” wait task number:” + taskQueue.size();
}
/**
- 内部类,工作线程
*/
private class WorkThread extends Thread{
@Override
public void run(){
Runnable r = null;
try {
while (!isInterrupted()) {
//监听阻塞队列,如果有任务,则执行相应的任务
r = taskQueue.take();
if(r!=null) {
System.out.println(getId()+” ready exec :”+r);
r.run();
}
r = null;//help gc;
}
} catch (Exception e) {
// TODO: handle exception
}
}
//停止线程
public void stopWorker() {
interrupt();
}
}
}
该线程池中,我们创建了workThreads用来保存运行的线程,使用BlockingQueue taskQueue用来保存我们的任务队列。
===============================================================================
1、定义WorkThread类,用来表示执行的线程,用于监听阻塞队列任务。
2、创建构建函数,我们将线程池进行初始化,并启动所有的工作线程。workThreads用来保存运行的线程,使用BlockingQueue taskQueue用来保存我们的任务队列
3、创建提交任务方法execute,用于提交我们的任务。
4、创建销毁线程池的方法destroy,用于销毁线程池。
之后我们编写测试类
import java.util.Random;
/**
-
@Auther: BlackKingW
-
@Date: 2019/4/14 12:09
-
@Description:
*/
public class TestMyThreadPool {
public static void main(String[] args) throws InterruptedException {
// 创建3个线程的线程池
MyThreadPool t = new MyThreadPool(3,0);
t.execute(new MyTask(“testA”));
t.execute(new MyTask(“testB”));
t.execute(new MyTask(“testC”));
t.execute(new MyTask(“testD”));
t.execute(new MyTask(“testE”));
System.out.println(t);
Thread.sleep(10000);
t.destroy();// 所有线程都执行完成才destory
System.out.println(t);
}
// 任务类
static class MyTask implements Runnable {
private String name;
private Random r = new Random();
public MyTask(Str
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
ing name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void run() {// 执行任务
try {
Thread.sleep(r.nextInt(1000)+2000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getId()+” sleep InterruptedException:”
+Thread.currentThread().isInterrupted());
}
System.out.println(“任务 ” + name + ” 完成”);
}
}
}
它的构造函数含有以下参数
1、如果工作线程数小于核心线程数,则创建工作线程
2、如果工作线程数等于或者大于核心线程数,则将任务提交到阻塞队列中
3、如果阻塞队列也满了,但线程数小于最大线程数,则创建新的线程
4、如果创建新的线程也满了,则执行任务饱和策略。
源码如下

3、如何合理配置线程池
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!