找回密码
 会员注册
查看: 41|回复: 0

Java实现异步的4种方式

[复制链接]

4

主题

0

回帖

13

积分

新手上路

积分
13
发表于 2024-9-3 18:51:15 | 显示全部楼层 |阅读模式
文章目录异步1、Future与Callable2.CompletableFuture3.Spring框架的异步支持3.1启动类开启对Async的支持@EnableAsync3.2配置自定义线程池3.3异步业务3.4调用异步业务方法4.使用消息队列4.1安装RabbitMq4.2使用4.3MQ消息丢失以及重复消费问题5、总结异步异步(Asynchronous)是指在进行多任务处理时,各个任务的执行不依赖于其他任务的完成,无需等待一个操作完成后再开始下一个操作。与之相对的是同步(Synchronous),同步操作需要按顺序执行,每个步骤必须等待前一个步骤完成才能开始。异步处理的优点包括但不限于:提高效率:允许程序在等待某个慢操作(如I/O操作)完成的同时,继续执行其他任务,提高了系统的整体响应速度和吞吐量。增强用户体验:在用户界面(UI)编程中,异步处理能防止界面冻结,保持应用的响应性。解耦:通过事件驱动或消息队列的方式,异步处理有助于解耦系统组件,使它们可以独立地开发、部署和扩展。可扩展性:对于大规模分布式系统,异步通信机制能够更容易地水平扩展,以应对高并发场景。实现异步编程的技术和框架有很多,根据不同的应用场景和技术栈选择合适的方法,例如:回调函数:是最基础的异步处理方式,通过传入一个函数作为参数,在异步操作完成时调用该函数。Promise/Promise链(JavaScript中)或Future(Java中):提供了更加优雅的异步编程模型,可以链式调用来组织异步操作。async/await(现代编程语言中广泛支持):进一步简化异步代码,使得异步代码看起来更像是同步代码,提高可读性和可维护性。消息队列和事件总线:用于解耦系统组件,通过发布-订阅模式或命令模式处理异步消息。线程池和并发库:如Java的Executor框架,用于管理线程资源,执行异步任务。选择合适的异步处理策略,可以显著提升软件系统的性能和用户体验。1、Future与CallableJava并发包中的Future和Callable接口提供了基本的异步编程模型。你可以通过ExecutorService提交一个实现了Callable的任务,它会返回一个Future对象。你可以在这个Future对象上调用get()方法来获取结果,这个方法会阻塞直到结果可用。Javaimportjava.util.concurrent.Callable;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.Future;publicclassAsyncExample{publicstaticvoidmain(String[]args)throwsException{ExecutorServiceexecutor=Executors.newSingleThreadExecutor();Callabletask=()->{Thread.sleep(2000);//模拟耗时操作return"Taskcompleted!";};Futurefuture=executor.submit(task);System.out.println("Doingsomethingelse...");//非阻塞方式检查结果是否准备好了while(!future.isDone()){Thread.sleep(100);System.out.println("Waitingforresult...");}System.out.println(future.get());//获取并打印结果executor.shutdown();}}12345678910111213141516171819202122232425262728292.CompletableFuture从Java8开始,CompletableFuture为异步编程提供了一个更强大、灵活的API,支持链式调用、组合多个异步操作以及更复杂的异步控制流。importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.ExecutionException;publicclassAsyncExampleWithCompletableFuture{publicstaticvoidmain(String[]args){CompletableFuture.supplyAsync(()->{sleep(2000);//模拟耗时操作return"Hello";}).thenAccept(result->System.out.println("Result:"+result));System.out.println("Doingsomethingelseconcurrently...");}privatestaticvoidsleep(intmillis){try{Thread.sleep(millis);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}}1234567891011121314151617181920213.Spring框架的异步支持如果你的项目使用了Spring框架,Spring提供了对异步方法的直接支持。你只需要用@Async注解标记希望异步执行的方法,并配置一个异步任务执行器(TaskExecutor)。3.1启动类开启对Async的支持@EnableAsync@SpringBootApplication@EnableScheduling@EnableAsync@MapperScan("com.example.demo.dao")publicclassSpringBoot3DemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(SpringBoot3DemoApplication.class,args);}}12345678910113.2配置自定义线程池@ConfigurationpublicclassAsyncConfig{@Bean(name="myAsyncThreadPool")publicThreadPoolTaskExecutorasyncThreadPool(){ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();executor.setCorePoolSize(5);//核心线程数executor.setMaxPoolSize(10);//最大线程数executor.setQueueCapacity(200);//队列大小executor.setThreadNamePrefix("Async-");//线程前缀名executor.initialize();returnexecutor;}}123456789101112133.3异步业务@Service@Slf4jpublicclassAsyncService{@Async("myAsyncThreadPool")publicvoidasyncMethod1(){log.info("asyncMethod1start");try{//发送短信...Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}log.info("发送短信成功");}@Async("myAsyncThreadPool")publicvoidasyncMethod2(){log.info("asyncMethod2start");try{//通知物流...Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}log.info("通知物流成功");}}12345678910111213141516171819202122232425263.4调用异步业务方法@Slf4j@RestController@Tag(name="测试控制器")@RequestMapping("test")publicclassTestController{@ResourceprivateAsyncServiceasyncService;@Operation(summary="下单")@PostMapping("placeAnOrder")publicCommonResultplaceAnOrder(){//主线程-》参数校验、扣减库存、优惠券状态更新、创建订单//异步线程1-》发送短信asyncService.asyncMethod1();//异步线程2-》通知物流asyncService.asyncMethod2();returnCommonResult.SUCCESS("下单成功");}}12345678910111213141516171819204.使用消息队列对于更复杂的异步处理需求,特别是需要跨服务通信或解耦不同服务组件的情况,可以考虑引入消息队列(如RabbitMQ、Kafka等)。通过发布-订阅模式或点对点模式,将任务放入队列,由专门的消费者异步处理。4.1安装RabbitMqLinux下载安装RabbitMQwin10下安装RabbitMQ4.2使用RabbitMQ快速上手以及RabbitMQ交换机的四种模式4.3MQ消息丢失以及重复消费问题RabbitMQ解决消息丢失以及重复消费问题5、总结总结每种方案的选择取决于具体的应用场景、复杂度和性能要求。简单的异步任务可能仅需使用Future和Callable,而复杂的异步流程控制和跨服务通信则可能更适合采用CompletableFuture或消息队列。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-13 10:57 , Processed in 0.669052 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表