Java高级应用:线程池的全面讲解(干货)
线程池概述
在使用Java多线程时,创建和销毁线程是一个非常昂贵的操作,而且容易造成系统资源的浪费,损耗因此才出现了线程池技术。
线程池可以控制线程的创建数量,避免因为线程过多而导致系统资源的浪费;同时线程池也可以避免线程因为过度创建而导致系统崩溃。线程池的好处不仅在于它可以减轻主线程的压力,而且还可以提升程序的执行效率。
线程池的核心参数
为了达到高效率和可控性,线程池的设计引入了几个核心参数,包括:
- corePoolSize:线程池的核心线程数,线程池中始终保持这些线程,除非设置了 allowCoreThreadTimeOut。
- maximumPoolSize:线程池中允许存在的最大线程数,当工作队列满了之后,新加入的任务会开启新的线程,直到达到这个值。
- keepAliveTime:当线程池中线程数量大于 corePoolSize 时,多余的线程在使用完之后,会等待 keepAliveTime 长时间后如果没有新的任务,则会被回收。
- workQueue:存放未执行的任务队列,一般使用 BlockingQueue 来实现,有以下常用类型:
- ArrayBlockingQueue:一个基于数组结构的有界阻塞队列。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,通常默认为无界。
- SynchronousQueue:一个特殊的无缓冲等待队列,生产者线程必须等待消费者线程来获取产品。
- RejectedExecutionHandler:当线程池执行到 maxImumPoolSize 并且无法处理新任务时,会调用 RejectedExecutionHandler 的 rejectedExecution 方法。有以下常用类型:
- AbortPolicy:丢弃任务并抛出 RejectedExecutionException 异常。
- DiscardPolicy:丢弃任务,什么也不做。
- DiscardOldestPolicy:丢弃队列中等待最久的任务,然后重新尝试加入队列。
- CallerRunsPolicy:在调用者所在的线程中执行任务。
线程池的创建和销毁
Java中的线程池有两种创建方式:
- ExecutorService 线程池
// 定义一个线程池
ExecutorService executorService = Executors.newFixedThreadPool(5);
// 关闭线程池
executorService.shutdown();
- ThreadPoolExecutor 线程池
// 定义一个线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
// 执行任务
threadPoolExecutor.execute(() -> {
System.out.println("执行任务");
});
// 关闭线程池
threadPoolExecutor.shutdown();
线程池的应用场景
线程池的应用场景很多,下面以几个常见的场景为例进行说明:
1. 处理大量请求
当需要处理大量请求时,线程池可以很好的控制并发的数量,避免系统负荷过高。如下:
ExecutorService threadPool = Executors.newFixedThreadPool(10);
int requestCount = 1000;
for (int i = 0; i < requestCount; i++) {
threadPool.execute(() -> {
System.out.println("处理请求");
});
}
threadPool.shutdown();
2. 持续进行执行任务的应用
周期性任务执行需要根据时间来触发,可以使用 ScheduledThreadPoolExecutor 线程池,这个线程池可以定时执行任务。
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
final ScheduledFuture future = executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("执行任务");
}
}, 1, 10, TimeUnit.SECONDS);
通过上述例子,就可以完整地了解并应用线程池了。后续还可以通过实际开发中的应用场景进一步掌握线程池的使用技巧。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java高级应用:线程池的全面讲解(干货) - Python技术站