• Spring 与 JDK 线程池的简单使用


    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 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 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 executorResult = taskComponent.doTaskExecutor();
    	//Future 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 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.查看线程池是否已满,不满就创建一条线程执行任务,否则就按照策略(拒绝策略)处理无法执行的任务。

  • 相关阅读:
    LeetCode //C - 61. Rotate List
    Defocus(散焦)
    python大数据 pycharm中的面向对象-文件读写-异常
    数据结构之循环链表
    为什么Java中你写的swap()函数无法实现两数交换?你真的深入了解Java中的栈和堆了吗?
    Java NIO开发需要注意的陷阱
    针对我国——国产数据库进行分析
    【TCPDF】使用TCPDF导出PDF文件
    跟李沐学AI之计算性能+图像分类
    No module named ‘pyqt5‘解决办法
  • 原文地址:https://blog.csdn.net/Trouvailless/article/details/126817995