javajava 模拟 实现一个 ThreadPoolExecutor
Posted 九师兄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javajava 模拟 实现一个 ThreadPoolExecutor相关的知识,希望对你有一定的参考价值。
1.概述
这里参考:
硬核干货:4W字从源码上分析JUC线程池ThreadPoolExecutor的实现原理
面经手册 · 第21篇《手写线程池,对照学习ThreadPoolExecutor线程池实现原理!》
这里先参考ThreadPoolExecutor的实现并且进行简化,实现一个只有核心线程的线程池,要求如下:
- 暂时不考虑任务执行异常情况下的处理。
- 任务队列为无界队列。
- 线程池容量固定为核心线程数量。
- 暂时不考虑拒绝策略。
public class ThreadPoolTrader implements Executor
private final AtomicInteger ctl = new AtomicInteger(0);
private volatile int corePoolSize;
private volatile int maximumPoolSize;
private final BlockingQueue<Runnable> workQueue;
public ThreadPoolTrader(int corePoolSize, int maximumPoolSize, BlockingQueue<Runnable> workQueue)
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
@Override
public void execute(Runnable command)
int c = ctl.get();
if (c < corePoolSize)
if (!addWorker(command))
reject();
return;
if (!workQueue.offer(command))
if (!addWorker(command))
reject();
private boolean addWorker(Runnable firstTask)
if (ctl.get() >= maximumPoolSize) return false;
Worker worker = new Worker(firstTask);
worker.thread.start();
ctl.incrementAndGet();
return true;
private final class Worker implements Runnable
final Thread thread;
Runnable firstTask;
public Worker(Runnable firstTask)
this.thread = new Thread(this);
this.firstTask = firstTask;
@Override
public void run()
Runnable task = firstTask;
try
while (task != null || (task = getTask()) != null)
task.run();
if (ctl.get() > maximumPoolSize)
break;
task = null;
finally
ctl.decrementAndGet();
private Runnable getTask()
for (; ; )
try
System.out.println("workQueue.size:" + workQueue.size());
return workQueue.take();
catch (InterruptedException e)
e.printStackTrace();
private void reject()
throw new RuntimeException("Error!ctl.count:" + ctl.get() + " workQueue.size:" + workQueue.size());
public static void main(String[] args)
ThreadPoolTrader threadPoolTrader = new ThreadPoolTrader(2, 2, new ArrayBlockingQueue<Runnable>(10));
for (int i = 0; i < 10; i++)
int finalI = i;
threadPoolTrader.execute(() ->
try
Thread.sleep(1500);
catch (InterruptedException e)
e.printStackTrace();
System.out.println("任务编号:" + finalI);
);
// 测试结果
任务编号:1
任务编号:0
workQueue.size:8
workQueue.size:8
任务编号:3
workQueue.size:6
任务编号:2
workQueue.size:5
任务编号:5
workQueue.size:4
任务编号:4
workQueue.size:3
任务编号:7
workQueue.size:2
任务编号:6
workQueue.size:1
任务编号:8
任务编号:9
workQueue.size:0
workQueue.size:0
以上,关于线程池的实现还是非常简单的,从测试结果上已经可以把最核心的池化思想体现出来了。主要功能逻辑包括:
-
ctl
,用于记录线程池中线程数量。 -
corePoolSize
、maximumPoolSize,用于限制线程池容量。 -
workQueue
,线程池队列,也就是那些还不能被及时运行的线程,会被装入到这个队列中。 -
execute
,用于提交线程,这个是通用的接口方法。在这个方法里主要实现的就是,当前提交的线程是加入到worker、队列还是放弃。 -
addWorker
,主要是类 Worker 的具体操作,创建并执行线程。这里还包括了 getTask() 方法,也就是从队列中不断的获取未被执行的线程。
好,那么以上呢,就是这个简单线程池实现的具体体现。但如果深思熟虑就会发现这里需要很多完善,比如:线程池状态呢,不可能一直奔跑呀!?、线程池的锁呢,不会有并发问题吗?、线程池拒绝后的策略呢?,这些问题都没有在主流程解决,也正因为没有这些流程,所以上面的代码才更容易理解。
接下来,我们就开始分析线程池的源码,与我们实现的简单线程池参考对比,会更加容易理解😄!
看完这个可以看
先看使用
【高并发】java中的线程池 ThreadPoolExecutor
进阶版
【java】java中的线程池 ThreadPoolExecutor源码分析
进阶版
面经手册 · 第21篇《手写线程池,对照学习ThreadPoolExecutor线程池实现原理!》
以上是关于javajava 模拟 实现一个 ThreadPoolExecutor的主要内容,如果未能解决你的问题,请参考以下文章
javajava 实现 将 字符串 第一个字符 大写 或者 小写