线程池:
重用线程池,避免因线程的创建和销毁带来性能开销
带来风险:死锁,资源不足,并发错误,线程泄露,请求过载
Executor框架:
Java5
出现 java.util.cocurrent
包下
void execute(Runnable command)
子接口:ExecutorService
其实现类ThreadPool
1.corePoolSize:
线程池中的核⼼线程数,当提交⼀个任务时,线程池创建⼀个新线程执⾏任务,直到当前线程数等于 corePoolSize
;如果当前线程数为 corePoolSize
,继续提交的任务被保存到阻塞队列中,等待被执⾏;如果执⾏了线程池的 prestartAllCoreThreads()
⽅法,线程池会提前创建并启动所有核⼼线程。当线程数⼩于等于 corePoolSize
时,默认情况下线程会⼀直存活在线程池中,即使线程处于空闲状态。如果allowCoreThreadTimeOut
被设置为 true 时,⽆论线程数多少,那么线程处于空闲状态超过⼀定时间就会被销毁掉。
2.maximumPoolSize:
线程池中允许的最⼤线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执⾏任务,前提是当前线程数⼩于 maximumPoolSize
;
3.keepAliveTime:
线程空闲时的存活时间,即当线程没有任务执⾏时,继续存活的时间;默认情况下,该参数只在线程数⼤于 corePoolSize
时才有⽤;如果allowCoreThreadTimeOut
被设置为 true 时,⽆论线程数多少,线程处于空闲状态超过⼀定时间就会被销毁掉。
4.unit:keepAliveTime
的单位。 TimeUnit
是⼀个枚举类型,其包括:
NANOSECONDS :1微毫秒 = 1微秒 / 1000
MICROSECONDS :1微秒 = 1毫秒 / 100
MILLISECONDS :1毫秒 = 1秒 /1000
SECONDS :秒
MINUTES :分
HOURS :⼩时
DAYS :天
5.workQueue:
⽤来保存等待被执⾏的任务的阻塞队列,且任务必须实现 Runable 接⼝,有如下阻塞队列:
ArrayBlockingQueue :
基于数组结构的有界阻塞队列,按FIFO排序任务;
LinkedBlockingQuene :
基 于 链 表 结 构 的 ⽆ 界 阻 塞 队 列 , 按 FIFO 排 序 任 务 , 吞 吐 量 通 常 要 ⾼ 于ArrayBlockingQuene
;
SynchronousQuene :
⼀个不存储元素的阻塞队列,每个插⼊操作必须等到另⼀个线程调⽤移除操作,否则插⼊操作⼀直处于阻塞状态,吞吐量通常要⾼于 LinkedBlockingQuene
;
6.threadFactory:
创建线程的⼯⼚,通过⾃定义的线程⼯⼚可以给每个新建的线程设置⼀个具有识.线程名( Executors.defaultThreadFactory()
)
7.handler: 线程池的饱和策略,当阻塞队列满了,且没有空闲的⼯作线程,如果继续提交任务,必须采取⼀种
策略处理该任务,线程池提供了4种策略:
AbortPolicy :
直接抛出异常,默认策略;
CallerRunsPolicy :
⽤调⽤者所在的线程来执⾏任务;
DiscardOldestPolicy :
丢弃阻塞队列中靠最前的任务,并执⾏当前任务;
DiscardPolicy :
直接丢弃任务;
原子性:在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性
Executors
线程工具类
CachedThreadPool
:可缓存线程池,超过60秒闲置线程将被终止并从缓存中删除。
FixedThreadPool
:可重用固定个数的线程池
核心线程数量的底配置:
计算密集型的任务:核心线程数量 = CPU的核数 + 1
IO密集型的任务:核心线程数量 = CPU核数 * 2
ScheduledThreadPool
:支持定时及周期性任务执行。它的线程数量是固定的
scheduleAtFixedRate 方法
,如果要执行的任务耗时比任务执行的间隔时间长,下次任务执行的时间是上一次任务执行后就执行。(排队)
scheduleWithFixedDelay 方法
:下次任务的执行时间是在本次任务执行所需时间再加上间隔时间。
SingleThreadExecutor
:单线程的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先
级)执行。
阻塞队列:
Java.util.concurrent.BlockingQueue
不接受null,容量有界,线程安全
ArrBlockingQueue实现类
add() //容量不够抛异常
offer() //返回true/false
put() //会产生阻塞,要等到阻塞队列中有位置
poll() //取第一个,若没有返回null
take() //取第一个,返回String