线程池
好处
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
Runnable/execute和Callable/submit
- Runnable 接口不会返回结果或抛出检查异常,但是 Callable 接口可以。
execute()方法用于提交不需要返回值的任务,submit()方法用于提交需要返回值的任务。submit也可以传入Runnable,没有返回值但是可以从Futrue中看是否执行成功。
创建线程池
Executors工具类创建
FixedThreadPool 线程数量固定,新任务可能排队
- SingleThreadExecutor 线程只有1个,新任务可能排队
- CachedThreadPool 线程数量不固定,如果没有可用会新创建
- ScheduledThreadPool 给定延迟之后(一次或定期)执行任务
-
ThreadPoolExecutor创建
corePoolSize : 核心线程数定义了最小可以同时运行的线程数量。
- maximumPoolSize : 当队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
- workQueue: 当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。
keepAliveTime: 当线程池中的线程数量大于 corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 keepAliveTime才会被回收销毁;
饱和策略
AbortPolicy
- CallerRunsPolicy
- DiscardPolicy
- DiscardOldestPolicy
案例
ScheduledThreadPool
- SchedulingConfigurer
ScheduledTaskRegistrar ```java @Configuration public class ScheduledThreadPoolConfig implements SchedulingConfigurer {
private final int POOL_SIZE = 10;
@Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
} }
```