本文共 1706 字,大约阅读时间需要 5 分钟。
问题引入
重复创建和销毁线程的开销很大,可能会超过响应用户的时间
Java线程池创建方法
- newFixedThreadPool(int N)N为线程数
- newCachedThreadPool()处理大量短时间工作任务的线程池 1)试图缓存线程并重要,无缓存线程可用就创建新线程 2)如果系统闲置的时间超过阈值,则会被终止并移出缓存 3)如果长时间闲置的时候,不会消耗什么资源
- newSingleThreadExecutor()创建唯一线程,线程异常结束会有另一个线程取代它
- newSingleThreadScheduledExecutor与newScheduledThreadPool(int corePoolSize)定时或者周期性的工作调度,两者的区别在单一工作线程还是多个线程
- newWorkStealingPool()内部会构建FoekJoinPool,利用working-stealing算法,并行地处理任务,不保证处理顺序
Fork/Join框架(原理和mapreduce一样)
Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架
working-stealing算法
某个线程从其他队列里窃取任务来执行
为什么要使用线程池
- 降低资源消耗
- 提高线程的可管理性 (1)因为在请求时,线程已经存在,从而消除了线程创建所带来的延迟 (2)通过调整线程池中的线程数目,可以有效防止资源不足
三个Executor接口
(1)Executor:运行新任务的简单接口,将任务提交和任务执行细节解耦
(2)ExecutorService:具备管理执行器和任务生命周期的方法,提交任务机制更完善
(3)ScheduledExecutorService:支持Future和定期执行任务
ThreadPoolExecutor构造方法
// Java线程池的完整构造函数public ThreadPoolExecutor( int corePoolSize, // 线程池长期维持的线程数,即使线程处于Idle状态,也不会回收。 int maximumPoolSize, // 线程数的上限 long keepAliveTime, TimeUnit unit, // 超过corePoolSize的线程的idle时长, // 超过这个时间,多余的线程会被回收。 BlockingQueue workQueue, // 任务的排队队列 ThreadFactory threadFactory, // 新线程的产生方式 RejectedExecutionHandler handler) // 拒绝策略
handler:线程池的饱和策略
- AbortPolicy:直接抛出异常,这是默认策略
- CallerRunPolicy:用调用者所在的线程来执行任务
- DiscardOldestPolicy:丢弃队列中最靠前的任务,并执行当前任务
- DiscardPolicy:直接丢弃任务
Runnable和Callable
可以向线程池提交的任务有两种:Runnable和Callable,二者的区别如下:
方法签名不同,void Runnable.run(), V Callable.call() throws Exception
是否允许有返回值,Callable允许有返回值
是否允许抛出异常,Callable允许抛出异常。
Callable是JDK1.5时加入的接口,作为Runnable的一种补充,允许有返回值,允许抛出异常
线程池的状态
- Running:能接受新提交的任务,并且能处理阻塞队列中的任务
- shutdown:不再接受新提交的任务,但可以处理存量任务
- stop:不再接受新提交的任务,也不处理存量任务
- tidying:所有的任务都已经终止
- terminated:(标识)terminated()方法执行完后进入该状态
转载地址:http://brqen.baihongyu.com/