1.为什么要用线程池
线程池主要解决两个问题:一是当执行大量异步任务时线程池能够提供较好的性能。在不使用线程池时,每当需要执行异步任务时直接new一个线程来运行,而线程的创建和销毁是需要开销的。线程池里面的线程是可复用的,不需要每次执行异步任务时都重新创建和销毁线程。二是线程池提供了一种资源限制和管理的手段,比如可以限制线程的个数,动态新增线程等。每个ThreadPoolExecutor也保留了一些基本的统计数据,比如当前线程池完成的任务数目等。
线程池的创建有几种方式
1.
//使用Executors去创建
ExecutorService executorService = Executors.newFixedThreadPool(2);
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorService executorService = Executors.newScheduledThreadPool(2);
ExecutorService executorService = Executors.newCachedThreadPool();
2.
//使用ThreadPoolExecutor去创建
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
ThreadPoolExecutor executorOne = new ThreadPoolExecutor(20,20,1,
TimeUnit.MINUTES,new LinkedBlockingQueue<>(),threadFactory,new ThreadPoolExecutor.AbortPolicy());
Exeutors返回的线程池对象的缺点如下:
1.FixedThreadPool和SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而发生内存溢出现象(oom)
2.CachedThreadPool和ScheduledThreadPool:
允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致内存溢出现象(oom)