在Spring Boot2中使用CompletableFuture的方法教程
前言
在Spring Boot中有一個注釋@Async,可以幫助開發(fā)人員開發(fā)并發(fā)應用程序。但使用此功能非常棘手。在本博客中,我們將了解如何將此功能與CompletableFuture一起使用。我認為你已經(jīng)知道關(guān)于CompletableFuture的基礎(chǔ),所以我不會在這里重復這個概念。
首先,您需要使用@EnableAsync來注釋您的應用程序類,這個注釋告訴Spring查找使用@Async注釋的方法并在單獨的執(zhí)行程序中運行它們。
@SpringBootApplication
@EnableAsync
public class App {
RestTemplate
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
如果您查看有關(guān)使用CompletableFuture和@Async的Spring Boot示例,您會注意到他們使用此功能的方式基于REST請求,在我看來,我相信,它有點受限,它不會給你在其他情況下如何使用此功能的線索。例如,如果你有一個長期運行的任務(wù),你會怎么做?
// Source : https://spring.io/guides/gs/async-method/
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.CompletableFuture;
@Service
public class GitHubLookupService {
private static final Logger logger = LoggerFactory.getLogger(GitHubLookupService.class);
private final RestTemplate restTemplate;
public GitHubLookupService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
@Async
public CompletableFuture<User> findUser(String user) throws InterruptedException {
logger.info("Looking up " + user);
String url = String.format("https://api.github.com/users/%s", user);
User results = restTemplate.getForObject(url, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return CompletableFuture.completedFuture(results);
}
}
在FindUser(String user)中,它在主線程中使用CompletableFuture,此方法的主要任務(wù)是使用RestTemplate從github獲取數(shù)據(jù),功能是“執(zhí)行HTTP請求的同步客戶端”。如何使用長時間運行的任務(wù),如調(diào)用網(wǎng)絡(luò)功能,如從REST端點ping服務(wù)器?在這種情況下,您需要定制CompletableFuture。你不能簡單地調(diào)用:
return CompletableFuture.completedFuture(results);
如何使用CompletableFuture
要在代碼中使用@Async,您的方法必須返回Future或CompletableFuture,看一下下面的例子:
@Async
public CompletableFuture<Boolean> isServerAlive(String ip) {
CompletableFuture<Boolean> future = new CompletableFuture<Boolean>(){
@Override
public Boolean get() throws InterruptedException, ExecutionException {
InetAddress address = null;
try {
address = InetAddress.getByName(ip);
return address.isReachable(1000);
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
};
return future;
}
在這個例子中,我重寫了get()方法并返回CompletableFuture而沒有任何線程執(zhí)行器,事實上我們要求Spring在不同的線程中執(zhí)行@Async方法,但是我們不提供任何線程執(zhí)行器,只有后臺工作者中運行就足夠了。
download source code from github (本地下載)
注意:在這個例子中,我決定在Spring Boot中使用一個網(wǎng)絡(luò)函數(shù),僅僅是為了一個參數(shù)。但最好不要在REST端點中直接使用網(wǎng)絡(luò)功能,特別是當您希望立即獲得結(jié)果時。原因是:網(wǎng)絡(luò)功能是阻塞的,這意味著,如果你調(diào)用這個REST端點,您必須在端點等待獲取結(jié)果。強烈建議使用其他方法(如queue或push方法)(例如websocket)來調(diào)用阻塞函數(shù)。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
mybatis insert foreach循環(huán)插入方式
這篇文章主要介紹了mybatis insert foreach循環(huán)插入方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
Java如何將Excel數(shù)據(jù)導入到數(shù)據(jù)庫
這篇文章主要為大家詳細介紹了Java將Excel數(shù)據(jù)導入到數(shù)據(jù)庫的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
Java 處理超大數(shù)類型之BigInteger案例詳解
這篇文章主要介紹了Java 處理超大數(shù)類型之BigInteger案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09

