Spring 与 JDK 线程池的简单使用示例详解

作者:羁客% 时间:2023-08-20 04:02:59 

1.配置自定义共享线程池(Spring线程池)

@Configuration
@EnableAsync
public class ThreadPoolConfig{

//主要任务的调度,计划执行
 @Bean("taskScheduler")
 public Executor createScheduler(){
   // 创建一个线程池对象
       ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
       // 定义一个线程池大小
       scheduler.setPoolSize(100);
       // 线程池名的前缀
       scheduler.setThreadNamePrefix("taskScheduler-");
       // 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
       scheduler.setWaitForTasksToCompleteOnShutdown(true);
       // 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
       scheduler.setAwaitTerminationSeconds(60);
       // 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
       scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
   return scheduler;
 }

//主要任务的执行
 @Bean("taskExecutor")
 public Executor createExecutor(){
   // 创建一个线程池对象
       ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
       executor.setCorePoolSize(10);
       //最大线程数
       executor.setMaxPoolSize(30);
       //队列容量
       executor.setQueueCapacity(100);
       //活跃时间
       executor.setKeepAliveSeconds(60);
       //线程名字前缀
       executor.setThreadNamePrefix("taskExecutor-");
       // 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
       executor.setWaitForTasksToCompleteOnShutdown(true);
       // 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
       executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
       return executor;
 }

}

2.编写执行任务对象与具体任务逻辑方法

@Component
public class TaskComponent{
 @Async("taskExecutor")
 public void doTaskExecutor() {
System.out.println("任务开始执行!!!");
 //具体的执行任务
//。。。。。。。
 }

//  //有返回值(ObjectVo为自己定义的返回类型)
//@Async("taskExecutor")
//public Future<ObjectVo> doTaskExecutor() {
//System.out.println("任务开始执行!!!");
//  //具体的执行任务
////。。。。。。。
//ObjectVo result=new ObjectVo();
//return new AsyncResult<>(result);
//}
 @Async("taskScheduler")
 public void doTaskScheduler() {
System.out.println("任务开始调度!!!");
 //具体的调度任务
//。。。。。。。
 }

//  //有返回值(ObjectVo为自己定义的返回类型)
//@Async("taskScheduler")
//public Future<ObjectVo> doTaskScheduler() {
//System.out.println("任务开始调度!!!");
//  //具体的调度任务
////。。。。。。。
//ObjectVo result=new ObjectVo();
//return new AsyncResult<>(result);
//}
}

3.调用任务方法(在哪调用都可以,根据自己业务需求在合适的地方调用即可)

@Service
public class UserServiceImpl implements UserService{
 @Autowired
 private TaskComponent taskComponent;
 //测试任务执行与调用
 @SneakyThrows
 @Override
 public void testTask(){
//没有返回值
taskComponent.doTaskExecutor();
taskComponent.doTaskScheduler();

//有返回值
//Future<ObjectVo> executorResult = taskComponent.doTaskExecutor();
//Future<ObjectVo> schedulerResult = taskComponent.doTaskScheduler();
//System.out.println(executorResult.get());
//System.out.println(schedulerResult.get());
 }
}

===============Executors结构========jdk自带线程池==========

1.任务(Runnable,Callable)

2.任务的执行(Executor,ExecutorService 接口,ThreadPoolExecutor,ScheduledThreadExecutor实现类)

3.计算结果(返回结果 Future接口,FutureTask实现类)

===============Executors现成的线程池========jdk自带线程池====

1 Executors.FixedThreadPool 核心数=容纳的最大线程数=N

* 队列(当队列过多时,会造成无限循环)

2 Executors.CachedThreadPool 容纳的最大线程数= *  

主线程提交任务的速度高于 maximumPoolSize中线程处理任务的速度时 CachedThreadPool将会不断的创建新的线程,

在极端情况下, 

CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源

3 Executors.SingleThreadExecutor 核心数=容纳的最大线程数=1 始终保持只有一个线程在执行 

* 队列(当队列过多时,会造成无限循环)

===============自定义Executors===========jdk自带线程池====================

ExecuteService threadPool = new ThreadPoolExecutor(int corePoolSize,
                int maximumPoolSize,
                long keepAliveTime,
                TimeUnit unit,
                BlockingQueue<Runnable> workQueue,
                ThreadFactory threadFactory,
                RejectedExecutionHandler handler);

//设置线程池的前缀

ThreadFactory threadFactory = new ThreadFactoryBuilder()

.setNameFormat("trhead-pool-%d").build();

//设置决绝策略

RejectedExecutionHandler: 

AbortPolicy:抛出RejectedExecutionException

CallerRunsPolicy:直接在execute方法的调用线程中运行被拒绝的任务。

DiscardOldestPolicy:放弃最旧的未处理请求,重试execute。

DiscardPolicy:丢弃被拒绝的任务。

================处理流程===================jdk 与 spring =====================

1.核心线程池是否在执行任务,不在执行就选一条线程执行,否则查看核心线程池是否已满

2.核心线程池是否满,不满则创建一条线程执行,否值查看队列是否已满

3.队列是否满,队列不满加入队列,否则查看线程池是否已满

4.线程池是否已满,线程池不满创建一条线程池,否则根据决绝策略处理

# 1.当一个任务被提交到线程池时,首先查看线程池的核心线程是否都在执行任务,否就选择一条线程执行任务,是就执行第二步。

# 2.查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第三步。

# 3.查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第四步。

# 4.查看线程池是否已满,不满就创建一条线程执行任务,否则就按照策略(拒绝策略)处理无法执行的任务。

来源:https://blog.csdn.net/qq_37778018/article/details/126767305

标签:Spring,JDK,线程池
0
投稿

猜你喜欢

  • C# 9.0 特性全面总结

    2023-07-21 16:28:19
  • Android用PopupWindow实现自定义Dailog

    2023-11-03 13:34:57
  • c#中使用BackgroundWorker的实现

    2023-05-04 08:51:01
  • Java编写多功能万年历程序的实例分享

    2023-11-23 07:39:50
  • Java 多线程学习详细总结

    2023-11-18 22:55:24
  • 详解Android中Notification的使用方法

    2023-02-07 13:17:39
  • Android登录记住多个密码的实现方法

    2021-12-08 00:33:15
  • Java代码实现微信页面滚动防露底(核心代码)

    2023-11-10 13:47:08
  • SpringBoot整合jersey的示例代码

    2021-08-28 05:23:12
  • java 数据结构并查集详解

    2023-01-22 03:52:24
  • java ssm框架实现分页功能的示例代码(oracle)

    2021-10-31 01:14:40
  • Maven setting.xml配置文件详解

    2023-06-28 00:33:41
  • Java通过Fork/Join优化并行计算

    2023-01-27 21:28:36
  • java多线程详细总结

    2023-01-10 14:16:04
  • Android视频悬浮窗口实现的示例代码

    2022-08-01 06:50:33
  • Android短信备份及数据插入实现代码解析

    2023-07-25 02:41:12
  • 深入了解JAVA HASHMAP的死循环

    2023-11-28 00:32:12
  • Java中如何动态创建接口的实现方法

    2023-11-25 15:13:02
  • C#实现获取一年中是第几个星期的方法

    2023-12-04 02:02:46
  • 海量数据去重排序bitmap(位图法)在java中实现的两种方法

    2022-10-10 17:27:36
  • asp之家 软件编程 m.aspxhome.com