创建线程池可以利用自带的Excutors以及ThreadPoolExcutor自定义七大参数自己创建线程池
(核心线程数,
最大线程数,
非核心线程存活时间,
时间单位,
拒绝策略(直接丢弃,丢弃最早加入阻塞队列的,callerrunspolicy回调主线程执行,可能阻塞线程池中的任务,所以要想不丢失任务一般不是用这种策略,而是扩大阻塞队列;或者采用对任务持久化的策略,实现RejectedExecutionHandler
接口自定义拒绝策略,当阻塞队列满了之后存入Mysql数据库中,并继承BlockingQueue实现混合阻塞队列,重写take方法,取任务时优先从数据库取,然后再从阻塞队列里取),
阻塞队列,
线程工厂(重写这里可以定义线程的名字))
Excutors和ThreadPoolExcutor都是实现了ExcutorService,一般建议用自己定义创建线程池的方法,why?
Excutors中的singleThreadExcutor和FixedThreadPool使用的LinkedBlockingQueue,是没有大小限制的,如果一直添加任务则有OOM的风险,CachedThreadPool可以无限创建线程,如果任务执行过慢可能会创建大量线程,也有OOM的风险。
线程池中线程异常,销毁还是复用?
1、excute()提交任务,异常如果没有被catch则会使线程终止,并将异常打印在控制台。会创建新线程来保持线程数量不变
2、submit()提交,异常会被封装在submit提交的future对象中,可以调用future.get()显示,不会使线程终止,可继续执行。
Future是什么?
Future主要体现了异步的思想,可以在创建线程执行任务时去干别的,回来后可以调用方法判断任务是否执行完毕,并可获得执行结果。还可以用来取消任务。
futuretask是future接口的实现类,可以接收runnable callable(也被转化为runnable)接口,实际对callable结果做了封装,管理了执行情况,保存了callable的call方法的执行结果。