线程池

1.原因

创建线程与销毁线程需要消耗资源,

2.目的

保活线程,提高系统的性能

3.线程池包含任务队列与线程池子

1)任务队列获取任务
2)没有任务时阻塞
3)queueSize和core线程数(执行任务的线程数,也就是初始化线程数)、max线程数,当超core线程数并且queueSize达到了最大值,且线程数没有超过max,那么启动新的线程
4)keepalive时间,超出core线程数的数量,设置存活时间,超出这个时间之后,回收线程,节约资源。这么设计原因?为了防止流量突然上涨
5) 任务队列是多线程竞争的是不是需要同步?
java中同步队列是BlockingQueue接口
6)当队列满了且达到了MAX线程数的大小如何处理?
RejectHandler接口,默认抛出RejectException

4.Future接口

1)需要查看任务是否执行完毕或者抛出异常
2)需要等待任务执行完成
runnable 没有返回值,不能抛出异常,callable则可以

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    // c = -536870911(状态位)
    int c = ctl.get();
    //  工作线程数量小于核心线程池设定数,则创建线程。
    if (workerCountOf(c) < corePoolSize) {
        // 如果添加成功则直接返回
        if (addWorker(command, true))
            return;
        // 否则再次获取活动线程数量
        c = ctl.get();
    }
    // 如果线程池正在运行,并且添加进队列成功
    if (isRunning(c) && workQueue.offer(command)) {
        // 再次对线程池状态检查, 因为上面 addWorker 过了并且失败了,所以需要检查
        int recheck = ctl.get();
        // 如果状态不是运行状态,且从队列删除该任务成功并尝试停止线程池
        if (! isRunning(recheck) && remove(command))
            // 拒绝任务
            reject(command);
        // 如果当前工作线程数量为0(线程池已关闭),则添加一个 null 到队列中
        else if (workerCountOf(recheck) == 0)
            // 添加个空的任务
            addWorker(null, false);
    }
    // 如果添加队列失败,则创建一个任务线程,如果失败,则拒绝
    else if (!addWorker(command, false))
        // 拒绝
        reject(command);
    }
}

addwork 创建线程 , workQueue.offer(command) 添加队列(将任务添加到阻塞队列中)
如果正在工作的的线程小于设置的核心线程,则创建线程,如过正在工作的线程大于核心线程数,则试图放入任务的队列,如果失败,则尝创建一个maxnumpoolSize的任务,注意:在remove方法中,该方法已经试图停止线程池的运行

1) addWorker方法 - 创建线程池
private boolean addWorker(Runnable firstTask, boolean core)

第一个参数为Runnable 类型,代表线程池中的某个线程的第一个任务,第二个参数如果是true,则创建核心线程,如果是false,则创建maxnumPoolSize 线程,这两个线程的生命周期是不同的。

2) Worker.runWorker(Worker w) 方法——-线程池的最核心方法
final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                        afterExecute(task, thrown);
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

首先执行firstTask的run方法,然后循环获取阻塞队列中的任务,并且调用他们的run方法,如果线程池中的任务异常,则抛出异常并停止运行线程池。
初始化的核心线程数是直接调用start方法启动线程的,启动之后,这个线程不关闭,而是在阻塞队列上等待,如果有任务就会执行任务的run方法,而不是start方法

你可能感兴趣的:(线程池)