我们知道一个进程可以把任务分成多个部分交给线程执行,多线程技术减少了CPU闲置时间,增加了程序并发性。
假设创建线程的时间为t1,执行任务的时间为t2,销毁线程的时间为t3。如果(t1+t2)>t3那么线程的创建和销毁就消耗了太多的资源,因此引进了线程池的概念。
一、 线程池的组成结构
一个线程池包括四个基本部分
1.线程管理池(ThreadPool):用于创建并管理线程池,有创建,销毁,添加新任务;
2.工作线程(PoolWorker):线程池中的线程在没有任务的时候处于等待状态,可以循
环的执行任务;
3.任务接口(Task):每个任务必须实现接口,用来提供工作线程调度任务的执行,规定了任务的入口以及执行结束的收尾工作和任务的执行状态等;
4.任务队列:用于存放没有处理的任务,提供一种缓存机制。
二、常见的线程池种类
1.CachedThreadPool(可缓存的线程池)
2.SecudleThreadPool(周期性执行任务的线程池)
3.SingleThreadPool(单线程线程池)
4.FixedThreadPool(定常的线程池)
三、线程池的工作流程
拿存在核心线程的线程池为例,这样其他线程池也很容易了解了!
在这里我们要注意:核心线程池满了之后是判断任务队列是否满,而不是创建非核心线程,在线程池中只有核心线程是永久存在的,其他线程都有自己的生命周期,时间一到线程就会被销毁。
当创建的线程数超过了最大容量,那么操作系统就会调用handle处理机制:
1.AbortPolicy:不执行新任务,直接抛出异常
2.DisCardPolicy:不执行新任务,也不抛异常
3.DisCard OldSetPolicy,新任务替换任务队列的第一个任务
4.CallerRunsPolicy:直接调用execute执行当前任务。
四、线程池的好处
线程池可以限制系统中执行线程的数量。 针对一些需要处理的短小而数量巨多的线程
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。
五、小结
Java中的线程池的顶级接口是Executor,我们真正使用的是ExecutorService,他的默认实现是ThreadPoolExecutor;
创建线程池的方式:
ExecutorService pool = Executors.newCachedThreadPool();
什么是Executor框架?
Executor 框架是一个根据一组执行策略调用、调度、执行和控制的异步任务的框架。利用它可以方便地创建线程池。