线程池如何做到线程复用的

2022-06-20 20:04:41 浏览数 (1)

一个线程在运行结束后, 是不能再次调用start() 方法启动的.

那JDK中的线程池是如何做到线程回收以及复用的呢?

复用原理

复用原理很简单, 就是生产者消费模式

将提交的线程任务写入任务队列, 线程池中的一个线程不断的从任务队列中拿出任务并执行.

代码语言:javascript复制
代码语言:javascript复制
BlockingQueueworkQueue = new ArrayBlockingQueue(10);
for(;;){
    Runnable r =  workQueue.take();
    r.run();
}

线程复用

在线程池(ThreadPoolExecutor)中, 线程复用过程也是类似的.

1. 向线程池提交任务之后,

如果当前执行中的线程数是否小于核心线程数(corePoolSize), 则执行addWorker()方法, 直接执行任务;

否则, 将任务添加到任务队列(workQueue)中.

代码语言:javascript复制
代码语言:javascript复制
public void execute(Runnable command) {
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
    }
    if (isRunning(c) && workQueue.offer(command)) {
    }
    else if (!addWorker(command, false))
        reject(command);
}

2. 执行任务时, 首先会创建一个封装了任务和线程信息的Worker对象, 启动并执行worker.

代码语言:javascript复制
代码语言:javascript复制
private boolean addWorker(Runnable firstTask, boolean core) {
       w = new Worker(firstTask);        
       final Thread t = w.thread;
       t.start(); 
}

Worker对象封装任务与线程.

代码语言:javascript复制
代码语言:javascript复制
private final class Worker extends AbstractQueuedSynchronizer    
    implements Runnable {
    Runnable firstTask;
    Worker(Runnable firstTask) {
        setState(-1); // inhibit interrupts until runWorker
        this.firstTask = firstTask;
        this.thread = getThreadFactory().newThread(this);
    }
    public void run() {
        runWorker(this);
    }}

3. worker线程启动后, 会执行runWorker()方法,

会根据条件worker.task != null 优先执行提交的任务;

后续执行时, 会根据(task = getTask()), 从任务队列(workQueue)中取出task, 并继续执行.

代码语言:javascript复制
代码语言:javascript复制
final void runWorker(Worker w) {Runnable task = w.firstTask;
        while (task != null || (task = getTask()) != null) {
          task.run();
        }
}

4. 从任务队列(workQueue)中取出task

代码语言:javascript复制
代码语言:javascript复制
private Runnable getTask() {
     Runnable r = timed ?
        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
        workQueue.take();
        return r;
 }

处理流程如下:

0 人点赞