(1)向线程池提交任务的两种方式:
方式一:使用execute方法(无返回值)
void execute(Runnable command);
方式二:使用submit方法(有返回值、可简单管理线程,并且可以处理异常)
Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
(2)关闭线程池:
pool.shutdown();
(1)任务按照次序执行 (2)池中只有唯一线程,并且存活时间是无限的 (3)线程繁忙时,新任务会进入到阻塞队列
场景:任务依次执行。
场景:处理CPU密集型的任务。在CPU被工作线程长时间使用的情况下,能确保尽可能少的分配线程。
弊端:内部使用无界队列来存放任务,当任务超过线程池最大容量需要处理时,队列无限增大,使服务器资源耗尽。
场景:快速处理突发性强、耗时较短的任务。
弊端:没有最大线程池数量限制。
// 内含一个线程池 newSingleThreadScheduledThreadPool(); // 内含n个线程池 newScheduledThreadPool(int corePoolSize);
通过scheduleAtFixedRate方法提交任务:
ScheduledFuture<?> scheduleAtFixedRate( Runnable command, // 首次执行任务延迟时间 long initialDelay, // 执行任务间隔时间 long period, // 计时单位 TimeUnit unit);
场景:周期性执行任务场景。
快捷创建线程池的方法存在严重的性能问题,所以大部分企业都禁止使用快捷线程池,要求通过标准构造器ThreadPoolExecutor构造线程池。
// 标准构造器 public ThreadPoolExecutor( // 核心线程数,即使线程空闲(idle),也不会回收 int corePoolSize, // 线程数上限 int maximumPoolSize, // 线程最大空闲(idle)时长 long keepAliveTime, TimeUnit unit, // 任务的排队队列 BlockingQueue<Runnable> workQueue, // 新线程的产生方式 ThreadFactory threadFactory, // 拒绝策略 RejectedExecutionHandler handler)