jdk线程池详解

来源:互联网 发布:qq飞车优化设置 编辑:程序博客网 时间:2024/06/01 23:06

1.线程池配置

    public ThreadPoolExecutor(intcorePoolSize,  //核心线程数

                              int maximumPoolSize, //最大线程数

                              long keepAliveTime,//空闲时间

                              TimeUnit unit,//时间单位

                              BlockingQueue<Runnable> workQueue,//等待队列

                              ThreadFactory threadFactory,//线程工厂

                              RejectedExecutionHandler handler) {//拒绝策略

        if (corePoolSize < 0 ||

            maximumPoolSize <= 0 ||

            maximumPoolSize <corePoolSize ||

            keepAliveTime < 0)

            throw new IllegalArgumentException();

        if (workQueue ==null ||threadFactory ==null ||handler == null)

            throw new NullPointerException();

        this.corePoolSize =corePoolSize;

        this.maximumPoolSize =maximumPoolSize;

        this.workQueue =workQueue;

        this.keepAliveTime =unit.toNanos(keepAliveTime);

        this.threadFactory =threadFactory;

        this.handler =handler;

    }

2.线程池执行过程

    public void execute(Runnablecommand) {

        if (command ==null)

            throw new NullPointerException();

        /*

         * Proceed in 3 steps:

         *

         * 1. If fewer than corePoolSize threads are running, try to

         * start a new thread with the given command as its first

         * task.  The call to addWorker atomically checks runState and

         * workerCount, and so prevents false alarms that would add

         * threads when it shouldn't, by returning false.

         *

         * 2. If a task can be successfully queued, then we still need

         * to double-check whether we should have added a thread

         * (because existing ones died since last checking) or that

         * the pool shut down since entry into this method. So we

         * recheck state and if necessary roll back the enqueuing if

         * stopped, or start a new thread if there are none.

         *

         * 3. If we cannot queue task, then we try to add a new

         * thread.  If it fails, we know we are shut down or saturated

         * and so reject the task.

         */

        int c = ctl.get();

        if (workerCountOf(c) <corePoolSize) {//初时线程数为0,小于核心线程数

            if (addWorker(command,true))//为true,添加core核心线程,方法内部二次验证,做个标记

                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);

    }


3.线程池worker工作原理

final void runWorker(Workerw) {

        Thread wt = Thread.currentThread();

        Runnable task = w.firstTask;

        w.firstTask =null;

        w.unlock(); // allow interrupts

        booleancompletedAbruptly =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 (RuntimeExceptionx) {

                        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);

        }

    }


4.空闲线程回收原理

 private Runnable getTask() {

        booleantimedOut =false;// Did the last poll() time out?


        retry:

        for (;;) {

            int c =ctl.get();

            int rs = runStateOf(c);


            // Check if queue empty only if necessary.

            if (rs >=SHUTDOWN && (rs >=STOP ||workQueue.isEmpty())) {

                decrementWorkerCount();

                return null;

            }


            booleantimed;     // Are workers subject to culling?


            for (;;) {

                int wc = workerCountOf(c);

                timed =allowCoreThreadTimeOut ||wc >corePoolSize;


                if (wc <=maximumPoolSize && ! (timedOut &&timed))

                    break;

                if (compareAndDecrementWorkerCount(c))

                    return null;

                c = ctl.get(); // Re-read ctl

                if (runStateOf(c) !=rs)

                    continue retry;

                // else CAS failed due to workerCount change; retry inner loop

            }


            try {

                Runnable r = timed ?

                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :

                    workQueue.take();

                if (r !=null)

                    return r;

                timedOut =true;

            } catch (InterruptedException retry) {

                timedOut = false;

            }

        }

    }


5.空闲线程退出机制

 

private void processWorkerExit(Workerw,booleancompletedAbruptly) {

        if (completedAbruptly)// If abrupt, then workerCount wasn't adjusted

            decrementWorkerCount();


        final ReentrantLock mainLock = this.mainLock;

        mainLock.lock();

        try {

            completedTaskCount +=w.completedTasks;

            workers.remove(w);

        } finally {

            mainLock.unlock();

        }


        tryTerminate();


        int c = ctl.get();

        if (runStateLessThan(c,STOP)) {

            if (!completedAbruptly) {

                intmin =allowCoreThreadTimeOut ? 0 :corePoolSize;

                if (min == 0 && !workQueue.isEmpty())

                    min = 1;

                if (workerCountOf(c) >=min)

                    return;// replacement not needed

            }

            addWorker(null,false);

        }

    }

6.定时线程池

schedule 执行一次

scheduleAtFixedRate 按照固定频率多次执行

创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的任何一个执行遇到异常,则后续执行都会被取消。否则,只能通过执行程序的取消或终止方法来终止该任务。如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行

scheduleWithFixedDelay 按照固定延时多次执行

创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程序的取消或终止方法来终止该任务。





0 0
原创粉丝点击