- 常用的创建线程 (常用的)
- 继承Thread,再通过Thread的start() (不推荐,不便于管理)
- 实现Runnable,再通过new Thread(runnable)包装后,start()
扩展Thread类与实现Runnable接口的比较
- 实现Runnable方式可以避免扩展thread方式由于Java单继承特性的缺点
- 实现Runnable的代码可以被多个线程共享,适合多个线程处理同一资源的情况
- 扩展Thread可以通过某些方式增强或修改类的功能.
《自己理解》 Thread 内部也是包含 runnable的 是它其中一个属性,自己可以创建。
也可以从外部传递。意思就是说 runnable remove或者 add thread 本体没有太大损耗。
线程池必备的基础知识点。
优点:
- 很好管理并复用线程,控制最大的并发数等。
- 实现任务线程队列缓存策略和拒绝机制。
- 隔离环境
/**
@param corePoolSize 核心线程
@param maximumPoolSize 容纳同时执行的 最大线程数。
@param keepAliveTime 线程空闲时间
@param unit 时间单位
@param workQueue 缓存策略
@param threadFactory 线程工厂
@param 拒绝策略
**/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
线程池的策略
- newFixedThreadPool
- newCachedThreadPool
- newScheduledThreadPool
- newSingleThreadExecutor
newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
固定数量线程,空闲状态也不会被回收。 当所有线程都处于工作状态,新任务出于等待状态。直到空闲出来。 只有核心线程并且不会被回收,意味着可以更快响应外界请求。
newCachedThreadPool
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程
线程数量不定的线程池,只有非核心线程。最大线程数为Interger.MAX_VALUE 是一个很大数。
如果没有可用线程会创建。如果线程池出于闲置状态时,都会因为超时被停止。
newScheduledThreadPool (wait …)
wait wait wait
newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
只有一个核心线程 所有任务都是在一个线程中按照顺序执行。
newWorkStealingPool ( jdk8 引入)
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
创建持有足够线程的线程池支持给定的并行度,并通过使用多个队列减少竞争。
rejectExcetion 策略
AbortPolicy(默认): 丢弃任务并且抛出RejectedExecutionException
DiscardPolicy: 丢弃任务,但是不抛出异常。(不推荐)
DiscardOldesPolicy: 抛弃队列中等待最久的任务,然后把当前任务加入队列中.
CallerRunsPolicy: 调用任务的run()方法绕过线程池直接执行。
线程池状态值的描述
ctl.get() // 包含线程数及线程池状态的Integer类型 的值
runStateOf() // 线程池状态的Integer类型
workerCountOf() // 工作线程数
最重要的:
runnig < shutDown < stop < tidying < terminated
(runnig) 线程池 能接受新任务
< (shutDown)不在接收新任务,但可以继续执行队列中的任务
< (stop) 全面拒绝,并中断正在处理的任务
< (tidying) 所有任务已经被终止
< (terminated) 已经清理完毕。
辅助 demo
- take/poll
- 无界/有界队列
- 自定义线程池大小
https://download.csdn.net/download/it_peng/11623175
参考:码出高效
https://www.zhihu.com/question/23212914