线程池进阶

线程池

线程

  • 创建方式

    • 继承 Thread 类型
    • 实现 Runnable接口
    • 实现 Callable 接口
  • Java线程生命状态

    • NEW ~新建
    • RUNNABLE ~运行
    • BLOCKED ~ 阻塞
    • WAITING ~ 等待
    • TIMED_WAITING ~超时等待
    • TERMINATED ~终结
  • 状态图

在这里插入图片描述

线程池

  • Why

    1. 频繁创建和销毁线程 会大大的降低系统效率
    2. 可以重用线程,减少线程的创建和销毁的开销,提高性能
    3. 提高响应速度,当任务到达是,不需要等待线程创建,就能立即执行
    4. 提高线程的可管理性, 线程是稀缺资源,不能无限制的创建,不仅会消耗系统资源,还会减低系统的稳定性。
  • How

    • 创建线程 new ThreadPoolExecutor

        
      	/**
           *
           * @param corePoolSize  核心线程数
           * @param maximumPoolSize   最大线程数
           * @param keepAliveTime  线程池维护线程所允许的空闲时间。当线程池中的线程数量大于corePoolSize的时
           * 候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了keepAliveTime;
           * @param unit  keepAliveTime的单位;
           * @param workQueue  等待被执行的任务的阻塞队列,且任务必须实现Runable接口
           * @param threadFactory  Executors.defaultThreadFactory() 来创建线
           * @param handler  线程池的饱和策略
           */
          public ThreadPoolExecutor(int corePoolSize,
                                    int maximumPoolSize,
                                    long keepAliveTime,
                                    TimeUnit unit,
                                    BlockingQueue<Runnable> workQueue,
                                    ThreadFactory threadFactory,
                                    RejectedExecutionHandler handler)
      
    • 执行任务

      • execute(Runnable command)

        执行没有返回值的任务

      • Future<?> submit(Runnable task)

        执行有返回值的线程任务

阻塞队列 workQueue
  • ArrayBlockingQueue:

    基于数组结构的有界阻塞队列,按FIFO排序任务

  • LinkedBlockingQuene

    基于链表结构的阻塞队列,按FIFO排序任务,吞吐量通常要高于ArrayBlockingQuene

  • SynchronousQuene

    一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQuene

    用于newCachedThreadPool线程池

  • priorityBlockingQuene

    具有优先级的无界阻塞队列

  • DelayedWorkQueue

    DelayedWorkQueue是一个基于堆的数据结构,类似于DelayQueue和PriorityQueue,

    用于ScheduledThreadPoolExecutor 定时线程池里面

线程状态
  • RUNNING

    线程池初始化状态是Running状态,能过接受新任务已经对已经接受的任务进行处理

  • SHUTDOWN

    状态切换: 调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN

    状态说明:处于shutdown状态时,不接受新任务,但能处理已添加的任务。

  • STOP

    状态切换: 调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

    状态说明:处于stop 状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。

  • TIDYING

    状态切换:SHUTDOWN -> TIDYING 阻塞队列为空并且线程池中执行的任务也为空

    ​ STOP -> TIDYING 线程池中执行的任务为空

    状态说明:所有任务已经终止

  • TERMINATED

    状态切换:TIDYING ->TERMINATED

    状态说明:线程池彻底终止,就变成TERMINATED状态

线程池原理

在这里插入图片描述

  • 流程图

    在这里插入图片描述

  • 源码解析

        public void execute(Runnable command) {
            if (command == null)
                throw new NullPointerException();
    		
            // clt记录着runState和workerCount
            int c = ctl.get();
            // 1.判断当前线程数是否小于核心线程数, 如果小于,创建新的线程
            if (workerCountOf(c) < corePoolSize) {
                if (addWorker(command, true))
                    return;
                c = ctl.get();
            }
            // 2. 如当前线程池的状态时运行状态,就将任务添加到队列当中
            if (isRunning(c) && workQueue.offer(command)) {
                // doubule check 检查线程池的状态,
                int recheck = ctl.get();
                // 如果不是运行状态,将之前加入到队列中的任务删除,且执行拒接策列
                if (! isRunning(recheck) && remove(command))
                    reject(command);
                // 如果工作线程数为0,启动一个新的非核心线程,
                else if (workerCountOf(recheck) == 0)
                    addWorker(null, false);
            }
            // 【非RUNNING状态 or workerCount >= corePoolSize 且workQueue已满】,直接新增非核心线程,如果新增失败则拒接该任务
            else if (!addWorker(command, false))
                reject(command);
        }
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值