一.为什么要用线程池
在多个任务的情况下,开启多个线程能提高处理效率.但开的线程数并不是越多越好.线程的创建与销毁需要时间.如果创建时间+销毁时间>执行任务实际这样就很不划算.一个线程默认最大栈大小1M,这个栈空间需要从系统内存中分配.线程过多,会消耗很多的内存.操作系统也需要频繁的切换线程上下文,影响性能.线程池的推出,就是为了方便的控制线程数量.
二. 线程池的构造
1.线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务.
2.工作线程:线程池中线程,在没有任务时处于等待状态,可以循环的执行任务
3.任务接口:每个任务必须实现的接口,以供工作线程调度任务的执行
4.任务队列:用于存放没有处理的任务.
三.线程池的创建
1.标准的线程池
public void test01(){ ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20)); for (int i = 0; i < 10; i++) { poolExecutor.submit(new Runnable() { @Override public void run() { System.out.println("Hello ThreadPoll!"); } }); } }
第一个参数是核心线程数,这个在初始化的时候就会创建.
第二个参数是最大线程数,当达到最大线程数时线程池就开始拒绝接受新任务.
第三个参数是线程空闲时间,当线程池中的线程(不包含核心线程),处于空闲状态超过这个配置的时间便会被回收.
第四个参数是线程空闲时间的时间单位
第五个参数是任务队列,当有任务提交时核心线程又处于忙碌状态时,会先把任务放到队列中.当队列满时来一个任务,会先判断线程池中数量是否大于最大线程数,如果小于最大线程数就会创建一个新的线程.如果线程池中线程数等于了最大线程数(第二个参数)则不再接收新的任务.
参数的配置尤其要注意队列大小的设置,如果不设队列的限定值,则是无界队列,这时线程池中最大线程数为核心线程数,并没有更好的提高效率.在使用过程中队列的大小要根据实际情况进配置.
2.线程池的其它创建方式
Executors.newFixedThreadPool(int count); 创建一个固定大小,任务队列容量无界的线程池.核心线程数=最大线程数
Executors.newCachedThreadPool(); 创建的是一个大小无界的缓冲线程池,任务加入池中,如果池中有空闲线程,则用空闲线程,如果无空闲线程则创建新的线程执行.池中的线程空闲超时时间为60秒.线程数随任务的多少变化.池的核心线程数=0,最大线程数等于int的最大值
Executors.newSingleThreadExecutor();只有一个线程来执行无界任务队列的单一线程池.