为什么使用线程池?
JVM使用的线程模型是KLT(Kernel Level Thread)模型。KLT是内核级线程模型,线程的创建、阻塞、销毁等操作都是在内核空间进行的。所以在对线程进行操作的时候,要进行用户态和内核态的交换,这个交换是比较耗时。所以为了减少线程频繁创建销毁带来的开销,所以使用池化技术来解决这个问题。
线程池的结构
简易线程池实现
package org.example.thread;
import java.util.HashSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Description:
* @Author: zhanghaiwei
* @CreateTime: 2022/11/21 17:01
*/
public class MyThreadPoolExecutor {
/**
* 任务队列
*/
private final BlockingQueue<Runnable> queue;
/**
* 线程池
*/
private final HashSet<Worker> pool = new HashSet<>();
private final int coreSize;
private volatile AtomicInteger aliveThread;
private final Lock lock = new ReentrantLock();
public MyThreadPoolExecutor(Integer poolSize, BlockingQueue<Runnable> queue){
coreSize = poolSize;
this.queue = queue;
}
public void execute(Runnable task){
if(aliveThread.get()>=coreSize){
try {
queue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try{
lock.lock();
if(aliveThread.get()>=coreSize){
queue.put(task);
}else{
Worker worker = new Worker();
pool.add(worker);
worker.setTask(task);
worker.thread.start();
aliveThread.getAndIncrement();
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
private class Worker implements Runnable{
public void setTask(Runnable task) {
this.task = task;
}
private Runnable task;
public Thread thread;
Worker(){
thread = new Thread(this);
}
@Override
public void run() {
runTask();
}
private void runTask() {
for(;;){
if(task!=null){
task.run();
}else{
try {
Runnable task = queue.take();
task.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
task=null;
}
}
}
}