线程池工作原理及创建

9 篇文章 0 订阅
3 篇文章 0 订阅

注:JDK1.8版本

线程池7个构造参数

线程池构造方法:

public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler)

1.corePoolSize 线程核心线程数(线程池中保留的线程数,即使它们是空闲的,默认情况下不会回收,除非设置allowCoreThreadTimeOut为true

allowCoreThreadTimeOut设置true时,会中断所有核心线程

interruptIdleWorkers(boolean) : void - java.util.concurrent.ThreadPoolExecutor

     interruptIdleWorkers() : void - java.util.concurrent.ThreadPoolExecutor

         allowCoreThreadTimeOut(boolean) : void - java.util.concurrent.ThreadPoolExecutor

2.maximumPoolSize 线程池中允许的最大线程数(maximumPoolSize = corePoolSize 不会有额外的创建线程,只有核心线程在工作)

3.keepAliveTime 线程空闲时间(线程数大于核心线程,剩余空闲线程最大等待时间)

4.unit 线程空闲时间单位

5.workQueue 线程池队列(线程池相关队列SynchronousQueue,LinkedBlockingQueue,DelayedWorkQueue )用于存放线程任务

SynchronousQueue :同步阻塞队列

分为两种模式,默认是非公平模式

公平模式:TransferQueue,队列任务先进先出

非公平模式:TransferStack,队列任务先进后出

队列任务添加满时,阻塞队列;队列任务消费为空时,阻塞队列

6.threadFactory 线程工厂用于创建线程

7.handler 拒绝策略

AbortPolicy:抛出java.util.concurrent.RejectedExecutionException异常

CallerRunsPolicy:用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务

DiscardOldestPolicy:丢弃任务队列中最旧任务

DiscardPolicy:丢弃当前将要加入队列的任务

线程池工作原理

1.execute 添加线程任务

public void execute(Runnable command) {

        if (command == null)

            throw new NullPointerException();

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

    }

2.addWorker 创建执行线程的worker

private boolean addWorker(Runnable firstTask, boolean core) {

        retry:

        for (;;) {

            int c = ctl.get();

            int rs = runStateOf(c);

            if (rs >= SHUTDOWN &&  //校验线程状态,队列是否为空

                ! (rs == SHUTDOWN &&

                   firstTask == null &&

                   ! workQueue.isEmpty()))

                return false;

            for (;;) {

                int wc = workerCountOf(c);

                if (wc >= CAPACITY ||

                    wc >= (core ? corePoolSize : maximumPoolSize)) // 校验当前工作线程数是否大于核心/最大线程数

                    return false;

                if (compareAndIncrementWorkerCount(c))

                    break retry;

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

                if (runStateOf(c) != rs)

                    continue retry;            }

        }

        boolean workerStarted = false;

        boolean workerAdded = false;

        Worker w = null;

        try {

            w = new Worker(firstTask);  //创建工作任务

            final Thread t = w.thread;

            if (t != null) {

                final ReentrantLock mainLock = this.mainLock;

                mainLock.lock();

                try {

                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||

                        (rs == SHUTDOWN && firstTask == null)) { // 校验线程状态

                        if (t.isAlive()) // precheck that t is startable

                            throw new IllegalThreadStateException();

                        workers.add(w);

                        int s = workers.size();  // 添加工作任务,并更新最大线程池数量

                        if (s > largestPoolSize)

                            largestPoolSize = s;

                        workerAdded = true;

                    }

                } finally {

                    mainLock.unlock();

                }

                if (workerAdded) { // 启动工作任务

                    t.start();

                    workerStarted = true;

                }

            }

        } finally {

            if (! workerStarted)

                addWorkerFailed(w);

        }

        return workerStarted;

    }

3.t.start() 开启工作任务

t.start()->Worker.run()->Worker.runWoker()

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 ((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);  // 移除工作任务

        }

    }

4.getTask() 执行]线程任务

private Runnable getTask() {

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

        for (;;) {

            int c = ctl.get();

            int rs = runStateOf(c);

            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { // 校验线程状态及队列是否为空

                decrementWorkerCount();

                return null;

            }

            int wc = workerCountOf(c);

            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))

                && (wc > 1 || workQueue.isEmpty())){ // 校验线程是否>最大线程/空闲超时且任务数>1/队列为空

                if (compareAndDecrementWorkerCount(c)) //cas减少任务数量

                    return null;

                continue;

            }

            try {

                Runnable r = timed ?

                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :workQueue.take(); //获取队列线程任务

                if (r != null)

                    return r;

                timedOut = true;

            } catch (InterruptedException retry) {

                timedOut = false;

            }

        }

    }

创建线程池4种情况

1.newCachedThreadPool 缓存线程池

new ThreadPoolExecutor(0, Integer.MAX_VALUE,

                                      60L, TimeUnit.SECONDS,

                                      new SynchronousQueue<Runnable>())

注:缓存线程池是一个无线扩容的线程池(核心线程为0,最大线程数不受限制),默认空闲时间60s,超过空闲时间时回收线程;线程没有回收前可重复利用

应用场景:流量洪峰且线程处理时间端(处理任务速度 > 提交任务速度,耗时少的任务)

2.newFixedThreadPool 固定线程池

 注:固定大小线程池(核心线程=最大线程),没有空闲线程,默认情况核心线程不会回收,默认情况队列无上限,大量线程任务进入队列可能导致内粗溢出

应用场景:限流处理减少系统承受压力(受内存限制,量少且任务急增情况,建议用在访问外部系统)

3.newSingleThreadExecutor 单例线程池

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {

return new FinalizableDelegatedExecutorService

            (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,

           new LinkedBlockingQueue<Runnable>(),  threadFactory));}

注:单列线程池(核心线程=最大线程=1)只有一个线程执行任务,没有空闲线程,默认情况核心线程不会回收,默认情况队列无上限,大量线程任务进入队列可能导致内粗溢出

应用场景:执行任务有先后顺序(量少且无时效场景)

4.newScheduledThreadPool 周期性线程池

public ScheduledThreadPoolExecutor(int corePoolSize) {

        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,

              new DelayedWorkQueue());

    }

注:周期性线程池(自定义核心线程,最大线程数量不限制);非核心线程执行完立马回收,默认情况队列无上限且有延迟效果

应用场景:定时任务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值