今天学习了JDK中的线程池,梳理了一下线程池的流程机制,尝试着写个简单的线程池
package com.hobson.day2;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
/**
* 重复造轮子-线程池
*
* @author haibin.tang
* @create 2020-04-13 2:59 PM
**/
public class WheelThreadPool implements Executor {
/**
* 核心线程数
*/
private int coreThreadSize;
/**
* 最大线程数
*/
private int maxThreadSize;
/**
* 任务队列
*/
private static BlockingQueue<Runnable> taskBlockQueue;
/**
* 工作线程: 核心线程+非核心线程
*/
private ConcurrentLinkedQueue<Worker> workers = new ConcurrentLinkedQueue<>();
public WheelThreadPool(int coreThreadSize, int maxThreadSize, BlockingQueue<Runnable> taskBlockQueue) {
this.coreThreadSize = coreThreadSize;
this.maxThreadSize = maxThreadSize;
WheelThreadPool.taskBlockQueue = taskBlockQueue;
}
@Override
public void execute(Runnable command) {
assert command != null;
//如果核心线程大于工作线程 则新建线程
if (coreThreadSize > workers.size()) {
doJob(command, true);
}
//如果工作线程小于最大线程数 则新建线程
else if (workers.size() < maxThreadSize){
doJob(command, false);
}
//工作线程>= 最大线程数,则把任务放入队列
else {
taskBlockQueue.add(command);
}
}
private void doJob(Runnable task, boolean coreThread) {
Worker worker = new Worker(task, coreThread);
workers.add(worker);
worker.getThread().start();
}
void runTask(Worker worker) {
worker.getTask().run();
Runnable task;
//自旋
for (;;) {
try {
if (!worker.isCoreThread()) {
//如果是非核心线程 则使用超时获取 任务
task = taskBlockQueue.poll(2000, TimeUnit.MICROSECONDS);
//如果任务未获取到 则把此工作线程移除队列
if (task == null) {
workers.remove(worker);
worker = null;
return;
}
} else {
//如果是核心线程 则使用take方法,该方法会阻塞 到获取到任务为止
task = taskBlockQueue.take();
}
task.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private class Worker implements Runnable {
private Runnable task;
private boolean coreThread;
private Thread thread;
Worker(Runnable task, boolean coreThread) {
this.task = task;
this.coreThread = coreThread;
thread = new Thread(this);
}
boolean isCoreThread() {
return coreThread;
}
@Override
public void run() {
runTask(this);
}
Runnable getTask() {
return task;
}
Thread getThread() {
return thread;
}
@Override
protected void finalize() throws Throwable {
System.out.println(String.format("work[%s]被gc", thread.getName()));
}
}
}
package com.hobson.day2;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @author haibin.tang
* @create 2020-04-13 4:46 PM
**/
public class Day2Main {
public static void main(String[] args) {
WheelThreadPool pool = new WheelThreadPool(2, 5, new LinkedBlockingQueue<>());
for (int index = 0; index < 100; ++index) {
int finalIndex = index;
pool.execute(() -> {
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread() + "-index -->> " + finalIndex);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
}
运行结果如下