线程池
1、为什么要用线程池。
在多线程的情况下,系统频繁开启关闭线程会造成大量的资源浪费,成本很高,同时有导致系统崩溃的风险。 线程池理解为一个池子里面有一堆线程,用的时候拿一个,用完放回去。这样就避免了不断地开启关闭。。
2、线程池分类。
总共有四种比较常见的线程池 newCachedThreadPool ,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor
newCachedThreadPool
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
该线程池是一个可缓存的线程池,就是说可以一直往里面增加线程,先查看当前线程池是否有可用的线程,没有就自己建一个。使用与执行生命周期短的异步任务。就是执行快的。。不然就会创建很多线程
newFixedThreadPool
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
这个线程池就相当于,创建一个固定数量的线程的线程池。多了就等着。
newScheduledThreadPool
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("延迟1秒后每3秒执行一次");
}
//延迟1秒后每3秒执行一次
}, 1, 3, TimeUnit.SECONDS);
一个可以设置定时服务的线程池,
newSingleThreadExecutor
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
单线程的线程池,任务只能一个个来,不能并发执行,因为只有一个线程
2、自定义线程池
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
上述构造函数,上面4个最终都是一个ThreadpoolExecutor
corePoolSize:初始线程数量
maximumPoolSize:最大线程数量
keepAliveTime:存活时间(超过该时间,那些maximumPoolSize-corePoolSize创建出来的线程会回收释放,只保留corePoolSize个数量)
unit:存活时间单位
BlockingQueue workQueue 任务队列(如果最大线程为10,队列大小为10,那么当21个任务同时进来时会报错,有一个任务会被丢弃不会被执行。。。)
BlockingQueue<Runnable> bq = new ArrayBlockingQueue<Runnable>(10);
// ThreadPoolExecutor:创建自定义线程池,池中保存的线程数为3,允许最大的线程数为6
ThreadPoolExecutor tpe = new ThreadPoolExecutor(3, 6, 50, TimeUnit.MILLISECONDS, bq);