为什么使用线程池?

JVM使用的线程模型是KLT(Kernel Level Thread)模型。KLT是内核级线程模型,线程的创建、阻塞、销毁等操作都是在内核空间进行的。所以在对线程进行操作的时候,要进行用户态和内核态的交换,这个交换是比较耗时。所以为了减少线程频繁创建销毁带来的开销,所以使用池化技术来解决这个问题。

线程池的结构

简易线程池实现

package org.example.pool;

import java.util.HashSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/** * @author zhw */
public class MyThreadPoolExecutor {
   
    private final BlockingQueue<Runnable> queue;
    private final HashSet<Worker> pool = new HashSet<>();
    private final int coreSize;
    private volatile int 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>=coreSize){
   
            try {
   
                queue.put(task);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
        }else{
   
            try{
   
                lock.lock();
                if(aliveThread>=coreSize){
   
                    queue.put(task);
                }else{
   
                    Worker worker = new Worker();
                    pool.add(worker);
                    worker.setTask(task);
                    worker.thread.start();
                    aliveThread++;
                }
            }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;
            }
        }
    }
}