深度理解Java线程池ThreadPoolExecutor

发布时间 2023-03-22 22:48:27作者: Edmond58

一.使用线程池的好处
1.提高系统性能和响应速度:线程池可以通过复用线程来减少线程的创建和销毁,从而减少了系统开销,提高了系统的性能和响应速度。
2.提高代码的可维护性:使用线程池可以将任务的执行与线程的创建和管理分离开来,使得代码更加清晰易懂,也更加容易维护。
3.提高代码的可复用性:线程池可以让不同的任务共享同一个线程池,从而提高代码的可复用性。
二.ThreadPoolExecutor线程池的参数解释

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

1.corePoolSize:核心线程池大小,即线程池中保留的线程数,即使它们处于空闲状态。如果新的任务提交给线程池时,核心线程池中的线程都在忙碌状态,那么新任务就会被添加到工作队列中等待执行。
2.maximumPoolSize:最大线程池大小,即线程池中最多可以创建的线程数。如果工作队列已满并且线程池中的线程数小于最大线程池大小,则会创建新的线程来执行任务。
3.keepAliveTime:空闲线程存活时间,即当一个线程处于空闲状态时,它最多可以存活多长时间。如果线程池中的线程数超过了核心线程池大小,空闲的线程将会被回收,直到线程池中的线程数等于核心线程池大小为止。
4.unit:keepAliveTime的时间单位。
5.workQueue:任务队列,用于存储等待执行的任务。当所有的核心线程都在执行任务时,新的任务会被添加到任务队列中等待执行。任务队列有多种实现方式,例如ArrayBlockingQueue、LinkedBlockingQueue等。
三.线程池的执行流程(execute方法)

        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);

1.当有任务需要执行时,首先判断当前线程池中的线程数是否小于核心线程数,如果是,则创建一个新的核心线程来执行任务。
2.如果当前线程池中的线程数已经达到核心线程数,则将任务放入任务队列中等待执行。
3.当任务队列已满时,如果当前线程池中的线程数还没有达到最大线程数,则创建新的非核心线程来执行任务。
4.如果当前线程池中的线程数已经达到最大线程数,则采取拒绝策略,例如抛出异常或者执行一些默认操作。
四.addWorker方法
1.参数解释
addWorker方法有两个参数,第一个参数表示要加入的线程,第二个参数表示该线程是否为核心线程。
2.执行流程
(1)获取线程池的状态,并检查线程池是否处于关闭状态。如果线程池已经关闭,且队列中还有任务等待执行,就不会再添加新的工作线程。如果线程池已经关闭,且队列中没有任务等待执行,也不会再添加新的工作线程。
(2)检查线程池中的工作线程数量是否已经达到了最大值,以及是否已经达到了核心线程数或最大线程数。如果工作线程数量已经达到了限制,就不会再添加新的工作线程。
(3)如果可以添加新的工作线程,方法会创建一个新的Worker对象,并将其添加到线程池中。如果添加成功,线程池会启动这个新的工作线程。