一、Thread
线程是并发编程的基础,也是程序执行的最小单元
Thread的6种状态:
- NEW: 新建状态,尚未启动
- RUNNABLE: 就绪状态,表示可运行状态,可能正在运行,或者在排队等待操作系统分配CPU
- BLOCKED: 阻塞状态,正在等待锁,以执行
synchronized方法 - WAITING: 等待状态,由于调用
Object.wait()、Thread.join()、LockSupport.park()之一 - TIMED_WAITING: 计时等待状态,比等待状态多了指定时间
- TERMINATED: 终止状态,表示线程已执行完成
Thread常用方法:
Thread.join():在一个线程中调用other.join(),当前线程会让出执行权给other线程,直到other线程执行完毕或达到指定时间,再执行当前线程
Thread.yield():表示给线程调度器一个当前线程愿意让出CPU的暗示,但是线程调度器可能会忽略这个暗示
二、ThreadPoolExecutor
线程池是为了避免线程频繁的创建和销毁带来的性能消耗,而建立的一种池化技术
阿里巴巴《Java开发手册》中规定:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的读者更加明确线程池的运行规则,规避资源耗尽的风险
Executors创建线程池对象的弊端:
-
FixedThreadPool和SingleThreadPool:允许请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,导致OOM -
CachedThreadPool和ScheduledThreadPool:允许创建线程数量为Integer.MAXVALUE,可能会创建大量的线程,导致OOM
ThreadPoolExecutor构造参数:
- corePoolSize: 核心线程数,没有任务也会常驻线程池
- maximumPoolSize: 线程池允许的最大线程数
- keepAliveTime: 非核心线程空闲时,销毁前的等待时间
- unit: 时间单位
- workQueue: 任务队列,仅保存由execute方法提交的任务
- threadFactory: 线程工厂,用于创建新线程
- RejectedExecutionHandler: 拒绝策略,任务队列已满并且不能创建新的线程时用到
执行规则
如果线程数小于核心线程数,直接创建新的线程执行任务
如果线程数等于或大于核心线程数,尝试将任务插入任务队列
如果无法插入任务队列,并且线程数未达到最大线程数,创建新的线程执行任务
如果已达到最大线程数,执行拒绝策略