二、Java開啟異步的兩種方式
1、注解開啟:@Async
1.1、配置異步的線程池
- 必須配置異步線程池,否則異步不會生效。
- @EnableAsync 注解:指定異步線程池。不指定默認使用:SimpleAsyncTaskExecutor線程池
- SimpleAsyncTaskExecutor是一個最簡單的線程池,它沒有任何的線程相關(guān)參數(shù)配置,它會為每個任務(wù)創(chuàng)建一個新的線程來執(zhí)行,因此不建議在生產(chǎn)環(huán)境中使用。
- 配置線程池見: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:方法上,說明這個方法是異步。不用寫我們自己配置的線程池
- 異步接口+實現(xiàn)類
接口
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();
}
實現(xiàn)類
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();
//不會等待異步方法執(zhí)行,直接返回前端數(shù)據(jù)
log.info("打?。簕}", "異步測試的-主方法2");
}
結(jié)果:
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!");
//異步執(zhí)行的代碼,也可以是方法,該方法不用單獨寫到其他類中。
this.async2("異步方法1!-end");
}, myIoThreadPool);
//不會等待異步方法執(zhí)行,直接返回前端數(shù)據(jù)
log.info("打?。簕}", "異步測試的-主方法2");
}
//異步需要執(zhí)行的方法,可以寫在同一個類中。
private void async2(String msg) {
//模仿io流耗時
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打?。簕}", msg);
}
結(jié)果:文章來源:http://www.zghlxwxcb.cn/news/detail-457457.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-457457.html
- 后續(xù)CompletableFuture的使用見:《Java的CompletableFuture,Java的多線程開發(fā)》
到了這里,關(guān)于Java開啟異步的兩種方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!