前言
在spring boot中有一個注釋@async,可以幫助開發人員開發并發應用程序。但使用此功能非常棘手。在本博客中,我們將了解如何將此功能與completablefuture一起使用。我認為你已經知道關于completablefuture的基礎,所以我不會在這里重復這個概念。
首先,您需要使用@enableasync來注釋您的應用程序類,這個注釋告訴spring查找使用@async注釋的方法并在單獨的執行程序中運行它們。
1
2
3
4
5
6
7
8
|
@springbootapplication @enableasync public class app { resttemplate public static void main(string[] args) { springapplication.run(app. class , args); } } |
如果您查看有關使用completablefuture和@async的spring boot示例,您會注意到他們使用此功能的方式基于rest請求,在我看來,我相信,它有點受限,它不會給你在其他情況下如何使用此功能的線索。例如,如果你有一個長期運行的任務,你會怎么做?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
// 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,此方法的主要任務是使用resttemplate從github獲取數據,功能是“執行http請求的同步客戶端”。如何使用長時間運行的任務,如調用網絡功能,如從rest端點ping服務器?在這種情況下,您需要定制completablefuture。你不能簡單地調用:
1
|
return completablefuture.completedfuture(results); |
如何使用completablefuture
要在代碼中使用@async,您的方法必須返回future或completablefuture,看一下下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@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而沒有任何線程執行器,事實上我們要求spring在不同的線程中執行@async方法,但是我們不提供任何線程執行器,只有后臺工作者中運行就足夠了。
download source code from github
注意:在這個例子中,我決定在spring boot中使用一個網絡函數,僅僅是為了一個參數。但最好不要在rest端點中直接使用網絡功能,特別是當您希望立即獲得結果時。原因是:網絡功能是阻塞的,這意味著,如果你調用這個rest端點,您必須在端點等待獲取結果。強烈建議使用其他方法(如queue或push方法)(例如websocket)來調用阻塞函數。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://www.jdon.com/51288