1、四种线程池类型
FixedThreadPool:线程数固定,且都是核心线程,不会被回收,用于大量长时间面向连接的线程
CachedThreadPool:线程数不固定,且都是非核心线程,时间一到立马被回收,用于执行一些生存期很短的异步型任务
ScheduledThreadPool:核心线程数固定,非核心线程数不固定
SingledThreadPool:单线程
一般我们都用CacheThreadPool,因为线程不固定,可回收。
2、ThreadPoolExecutor
上述四类线程池,常规的创建方式是通过Executors.newXXXThreadPool()来创建。
为了了解Executor的底层原理,我们还可以通过下面的方式来创建线程池:
new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,TIME_UNIT,queue)
1)对应四种线程池的创建方式如下:
FixedThreadPool:new ThreadPoolExecutor(100,100,0, TimeUnit.MILLISECONDS,new LinkedBlockingQueue)
ScheduledThreadPool:new ThreadPoolExecutor(100, INTEGER.MAX_VALUE,0, TimeUnit.MILLISECONDS,new DelayedWorkQueue)
ScheduledThreadPool不要自己写,因为DelayedWorkQueue是个内部类,自己写调不到这个类。
CachedThreadPool:new ThreadPoolExecutor(0,INTEGER.MAX_VALUE,60, TimeUnit.MILLISECONDS,new SynchronousQueue)
SingledThreadPool:new ThreadPoolExecutor(1,1,0, TimeUnit.MILLISECONDS,new LinkedBlockingQueue)
2)ThreadPoolExecutor中各参数描述:
CorePoolSize:核心线程数量,核心线程就是不被回收的线程
MaxPoolSize:最大线程数据,最大线程包括核心线程和非核心线程
KeepAliveTime:非核心线程被回收的等待时间
Queue:
ArrayBlockingQueue:有界阻塞队列,可设置长度
LinkedBlockingQueue:无界阻塞队列,队列长度无限,可不断往里放,除非OOM
SynchronousQueue:无元素阻塞队列,队列里面只能放一个元素,其它放不进去
FixedThreadPool线程池大小的考虑:
公式是:(线程等待时间/线程执行时间+1)*CPU核数
一般来说,CPU密集型的线程池,可以取n+1,n是CPU的核数;
IO密集型的线程池,可以取2n+1,n是CPU的核数。
3、线程池方法
execute(xxxThread):启动某线程,无返回值
Future<xxx> future = xxxxExecutorService.submit(xxxThread):启动某线程,有返回值
shutdown():关闭线程池(一定要写,并且写在finally里面)
4、Executor\Executors\ExecutorService\ThreadPoolExecutor
下面三个都是单个线程的功能类和接口:
Executor是线程池的最初始接口,里面只有一个execute()方法,用来执行Runnable
ExecutorService继承自Executor,增加了submit()方法,用来执行Callable,并能获取返回值
AbstractExecutorService是ExecutorService的实现类,实现了里面的方法
下面这个是线程池的类:
ThreadPoolExector继承自AbstractExecutorService,增加了线程池的创建方法。
最下面是线程池的创建类:
Executors可以通过ThreadPoolExector创建各种线程池,比如CachedThreadPool