异步线程池和同步线程池区别在哪_异步线程池和同步线程池区别在哪里

异步线程池和同步线程池区别在哪_异步线程池和同步线程池区别在哪里同步异步 定时任务 Spring线程池一、使用线程池的目的:处理异步任务(虽然有同步线程池SyncTaskExecutor,但是本质不算一个线程池,只有同步操作,没有异步调用) 二、同步与异步区别同步:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结

同步异步 定时任务 Spring线程池   一、使用线程池的目的:处理异步任务(虽然有同步线程池SyncTaskExecutor,但是本质不算一个线程池,只有同步操作,没有异步调用)       二、同步与异步区别   同步:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。   异步:异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。例如, 在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕;如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的业务子线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。       三、异步任务使用:@EnableAsync @Async(“线程池名”)   1. 注意事项:   a. 在Spring启动类上添加注解@EnableAsyn或者在你们线程池配置类添加@EnableAsyn(任选其一即可)   b. @Async不指定value则使用默认异步线程池   c. 使用此注解的方法的类对象,需要是spring管理下的bean对象(@Component)   2. Spring默认的异步线程池通过实现AsyncConfigurer接口进行配置   public interface AsyncConfigurer { Executor getAsyncExecutor(); AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(); }   Executor : 处理异步方法调用时要使用的实例,   AsyncUncaughtExceptionHandler :在使用返回类型的异步方法执行期间抛出异常时要使用的实例。   3. 实现举例:   @Configuration public class ThreadPoolConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); // 设置核心线程数 threadPool.setCorePoolSize(100); // 设置最大线程数 threadPool.setMaxPoolSize(200); // 线程池所使用的缓冲队列 threadPool.setQueueCapacity(50); threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); // 等待任务在关机时完成–表明等待所有线程执行完 threadPool.setWaitForTasksToCompleteOnShutdown(true); // 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止 threadPool.setAwaitTerminationSeconds(60); // 线程名称前缀 threadPool.setThreadNamePrefix(“Derry-Async-“); // 初始化线程 threadPool.initialize(); return threadPool; } / * 异步异常处理 * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return null; } }   4. Spring 已经实现的线程池   SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,默认每次调用都会创建一个新的线程。   SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作。只适用于不需要多线程的地方。   ConcurrentTaskExecutor:Executor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类。   SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的类。线程池同时被quartz和非quartz使用,才需要使用此类。   ThreadPoolTaskExecutor :最常使用,推荐。其实质是对java.util.concurrent.ThreadPoolExecutor的包装。   5. 自定义线程池:   @Component public class ThreadPool1 { //不指定Bean的name则按照方法名创建Bean注入容器 @Bean(name=”myAsync”) public Executor myAsync() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //最大线程数 executor.setMaxPoolSize(100); //核心线程数 executor.setCorePoolSize(10); //任务队列的大小 executor.setQueueCapacity(10); //线程前缀名 executor.setThreadNamePrefix(“My-Async-ThreadPool-1-“); //线程存活时间 executor.setKeepAliveSeconds(30); // 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止 executor.setAwaitTerminationSeconds(60); //等待任务在关机时完成–表明等待所有线程执行完 executor.setWaitForTasksToCompleteOnShutdown(true); / * 拒绝处理策略 * CallerRunsPolicy():交由调用方线程运行,比如 main 线程。 * AbortPolicy():直接抛出异常。 * DiscardPolicy():直接丢弃。 * DiscardOldestPolicy():丢弃队列中最老的任务。 */ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); //线程初始化 executor.initialize(); return executor; } }   自定义线程池需要给@Async指定value值   6. 使用多个线程池进行不同功能的线程隔离   使用多个线程池,把相同的任务放到同一个线程池中,可以起到隔离的作用,避免有线程出错时影响到其他线程池,例如只有一个线程池时,有两种任务,下单,处理图片,如果线程池被处理图片的任务占满,影响下单任务的进行       四、定时任务@EnableScheduling @Scheduled   说明:   a. @Scheduled 任务调度注解,主要用于配置定时任务;springboot默认的调度器线程池大小为 1(也就是说在多个方法上加上@schedule的,多个定时任务默认是加入延时队列依次同步执行的)   b. 在定时任务的方法上加上@Async就会把该定时任务交由异步线程池执行   配置默认调度器线程池的方法实现SchedulingConfigurer 接口   @Configuration public class ScheduledConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { scheduledTaskRegistrar.setScheduler(setTaskExecutors()); } @Bean(destroyMethod=”shutdown”) public Executor setTaskExecutors(){ return Executors.newScheduledThreadPool(3); // 3个线程来处理。 } }       五、代码演示   1. 定时任务演示 (为方便演示线程同步执行关系,调度器线程池大小已经配置为3)   // @Async @Scheduled(fixedDelay = 1000*3) public void test() throws InterruptedException { System.out.println(Thread.currentThread().getName()+”开始执行定时任务”); Thread.sleep(5000); System.out.println(Thread.currentThread().getName()+”定时任务执行完毕”+’   ’); }   运行结果:   pool-1-thread-1开始执行定时任务   pool-1-thread-1定时任务执行完毕   pool-1-thread-2开始执行定时任务   pool-1-thread-2定时任务执行完毕   该方法的定时任务3s执行一次,但是每次执行要睡眠5s,由于未开启异步所以需要等上一个线程执行完毕,下一个线程才能再次进入该方法。   2.加上@Async(未指定具体线程池,定时任务交由默认异步线程池执行)   @Async @Transactional @Scheduled(fixedDelay = 1000*3) public void test() throws InterruptedException { System.out.println(Thread.currentThread().getName()+”开始执行定时任务”); Thread.sleep(5000); System.out.println(Thread.currentThread().getName()+”定时任务执行完毕”+’   ’); }   运行结果:   Default-Async-ThreadPool-1开始执行定时任务 Default-Async-ThreadPool-2开始执行定时任务  //线程2在线程1运行期间便执行第二次定时任务,此即异步 Default-Async-ThreadPool-1定时任务执行完毕 Default-Async-ThreadPool-3开始执行定时任务  //线程3在线程2运行期间便执行第三次定时任务 Default-Async-ThreadPool-2定时任务执行完毕 Default-Async-ThreadPool-4开始执行定时任务 Default-Async-ThreadPool-3定时任务执行完毕   3. 加上@Async并指定具体线程池   @Async(“myAsync”) @Transactional @Scheduled(fixedDelay = 1000*3) public void test2() throws InterruptedException { System.out.println(Thread.currentThread().getName()+”开始执行定时任务”); Thread.sleep(5000); System.out.println(Thread.currentThread().getName()+”定时任务执行完毕”+’   ’); }   运行结果:   My-Async-ThreadPool-1-1开始执行定时任务 //线程名称发生变化,可见自定义线程池是生效的 My-Async-ThreadPool-1-2开始执行定时任务 My-Async-ThreadPool-1-1定时任务执行完毕 My-Async-ThreadPool-1-3开始执行定时任务 My-Async-ThreadPool-1-2定时任务执行完毕 My-Async-ThreadPool-1-4开始执行定时任务 My-Async-ThreadPool-1-3定时任务执行完毕       4.多线程池隔离异步执行不同定时任务   @Async //使用默认异步线程池 @Scheduled(fixedDelay = 1000*3) public void test() throws InterruptedException { System.out.println(Thread.currentThread().getName()+”开始执行定时任务”); Thread.sleep(5000); System.out.println(Thread.currentThread().getName()+”定时任务执行完毕”+’   ’); } @Async(“myAsync”) //使用自定义异步线程池 @Scheduled(fixedDelay = 1000*3) public void test2() throws InterruptedException { System.out.println(Thread.currentThread().getName()+”开始执行定时任务”); Thread.sleep(5000); System.out.println(Thread.currentThread().getName()+”定时任务执行完毕”+’   ’); }   运行结果:   Default-Async-ThreadPool-1开始执行定时任务 My-Async-ThreadPool-1-1开始执行定时任务 Default-Async-ThreadPool-2开始执行定时任务 My-Async-ThreadPool-1-2开始执行定时任务 Default-Async-ThreadPool-1定时任务执行完毕 My-Async-ThreadPool-1-1定时任务执行完毕 Default-Async-ThreadPool-3开始执行定时任务 My-Async-ThreadPool-1-3开始执行定时任务 Default-Async-ThreadPool-2定时任务执行完毕 Default-Async-ThreadPool-4开始执行定时任务 My-Async-ThreadPool-1-4开始执行定时任务 My-Async-ThreadPool-1-2定时任务执行完毕    六、相关随笔   1. Spring最常用的线程池类型ThreadPoolTaskExecutor参数原理详解:https://www.cnblogs.com/JNU-Iot-Longxin/p/15305313.html   2. ThreadPoolTaskExecutor另一种使用方式(不推荐):https://www.cnblogs.com/JNU-Iot-Longxin/p/15305050.html

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/50166.html

(0)
上一篇 2024年 9月 3日 下午2:56
下一篇 2024年 9月 3日

相关推荐

关注微信