为什么要使用线程池:
1、降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
2、提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
3、提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控
线程池对线程的管理性体现在:
1、创建和销毁由线程池管理,能够设置非核心线程的存活时间。
2、能够控制最大线程数。
3、提供定时执行的功能。
Executors类,封装了大部分我们常用到的线程池相关方法:
此类中包含了Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable类的工厂和utils方法。
此类支持以下方法:
1、使用常用的配置进行设置,创建和返回ExecutorService
2、使用常用的配置进行设置,创建和返回ScheduledExecutorService
3、创建并返回“包装”ExecutorService,该ExecutorService通过使特定的方法无法访问,来禁止重新配置。
4、创建并返回ThreadFactory,该ThreadFactory其能够根据指定状态创建的新线程。
5、从类似闭包形式创建和返回Callable,可以在需要Callable的执行方法中使用它们。
怎么使用线程池
Java中的线程池实现了Executor和ExecutorService接口,可以使用以下四种方法添加runnable任务:void execute(Runnable command);
Future> submit(Runnable task);
Future submit(Runnable task, T result);
Future submit(Callable task);
//后面三种方法都会返回一个Future对象,使得我们可以获取任务执行的状态。
上面为什么是用的“添加”,而不是“执行”呢?因为调用execute或submit方法之后,任务只是被添加到线程池的阻塞队列中,然后等待空闲线程的来执行。如果阻塞队列满了,并且线程池中的线程数也达到了设置的最大值,那么此时线程池饱和,任务无法添加,会被Reject。