二、Java开启异步的两种方式

1、注解开启:@Async

1.1、配置异步的线程池

  • 必须配置异步线程池,否则异步不会生效。
  • @EnableAsync 注解:指定异步线程池。不指定默认使用:SimpleAsyncTaskExecutor线程池
  • SimpleAsyncTaskExecutor是一个最简单的线程池,它没有任何的线程相关参数配置,它会为每个任务创建一个新的线程来执行,因此不建议在生产环境中使用。
  • 配置线程池见:https://www.cnblogs.com/kakarotto-chen/p/17428432.html
 
package com.cc.md.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/** IO型的线程池
* @author CC
* @since 2023/5/23 0023
*/
@Configuration
@EnableAsync
public class IoThreadPool {
public static final int THREAD_SIZE = 2 * (Runtime.getRuntime().availableProcessors());
public static final int QUEUE_SIZE = 1000;
@Bean(name = "myIoThreadPool")
public ThreadPoolTaskExecutor threadPoolExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(THREAD_SIZE);
executor.setMaxPoolSize(THREAD_SIZE);
executor.setQueueCapacity(QUEUE_SIZE);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.setKeepAliveSeconds(60);
executor.setAllowCoreThreadTimeOut(true);
executor.setAwaitTerminationSeconds(300);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("myIo-Th-Pool-");
executor.initialize();
return executor;
}
}

1.2、异步方法

  • 异步方法必须写在另一个类中,否则不生效
  • @Async可以打在类上、也可以打在方法上
 
1 @Async:类上,说明整个类中的方法都是异步。必须写我们自己配置的线程池 —— ("myIoThreadPool")
2 @Async:方法上,说明这个方法是异步。不用写我们自己配置的线程池
  • 异步接口+实现类

接口

 
package com.cc.md.service;
/**
* @author CC
* @since 2023/5/24 0024
*/
public interface IAsyncService {
/** 异步方法1
* @since 2023/5/24 0024
* @author CC
**/
void async1();
/** 异步方法2
* @since 2023/5/24 0024
* @author CC
**/
void async2();
}

实现类

 
package com.cc.md.service.impl;
import com.cc.md.service.IAsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
/** 1 @Async:类上,说明整个类中的方法都是异步。必须写我们自己配置的线程池 —— ("myIoThreadPool")
* 2 @Async:方法上,说明这个方法是异步。不用写我们自己配置的线程池
* @author CC
* @since 2023/5/24 0024
*/
@Service
@Async("myIoThreadPool")
public class AsyncServiceImpl implements IAsyncService {
private static final Logger log = LoggerFactory.getLogger(AsyncServiceImpl.class);
//类上写了@Async,这里就可以不写了。
//可以不写 ("myIoThreadPool")。因为在IoThreadPool中开启了异步,说明异步用的就是我们配置的io线程池
//如果类上面打了 @Async ,这里必须写:("myIoThreadPool")
@Override
//@Async
public void async1(){
//模仿io流耗时
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打印:{}", "异步方法1111!");
}
//@Async在类上面,说明这个方法也是异步方法。如果不打,无法开启异步。
@Override
public void async2(){
//模仿io流耗时
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打印:{}", "异步方法2222!");
}
}

1.3、测试

 
@Resource
private IAsyncService asyncService;
//开启异步1 —— @Async
@Test
public void test03() throws Exception {
log.info("打印:{}", "异步测试的-主方法1");
asyncService.async1();
asyncService.async2();
//不会等待异步方法执行,直接返回前端数据
log.info("打印:{}", "异步测试的-主方法2");
}

结果:

回到顶部

2、CompletableFuture的方式

使用:

 
@Resource(name = "myIoThreadPool")
private ThreadPoolTaskExecutor myIoThreadPool;
//开启异步2 —— CompletableFuture.runAsync()
@Test
public void test04() throws Exception {
log.info("打印:{}", "异步测试的-主方法1");
CompletableFuture.runAsync(() -> {
log.info("打印:{}", "异步方法1!");
//异步执行的代码,也可以是方法,该方法不用单独写到其他类中。
this.async2("异步方法1!-end");
}, myIoThreadPool);
//不会等待异步方法执行,直接返回前端数据
log.info("打印:{}", "异步测试的-主方法2");
}
//异步需要执行的方法,可以写在同一个类中。
private void async2(String msg) {
//模仿io流耗时
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打印:{}", msg);
}

结果:

  • 后续CompletableFuture的使用见:《Java的CompletableFuture,Java的多线程开发》
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野生的狒狒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值