成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

@Async怎么用

這篇文章主要為大家展示了“@Async怎么用”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“@Async怎么用”這篇文章吧。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了北戴河免費(fèi)建站歡迎大家使用!

使用@Async注解的方法會(huì)新開一個(gè)線程去執(zhí)行該方法,一些比較耗時(shí)的操作的操作使用該注解,交由Spring去管理線程的創(chuàng)建與銷毀。

接下來闡述一下自己的使用心得:
一、啟用@Async,個(gè)人在Springboot的啟動(dòng)類加上以下注解

@EnableAsync

二、在需要進(jìn)行異步操作的方法上加上@Async注解,注解不起作用的主要原因是被調(diào)用方法和調(diào)用方法處理同一個(gè)類中。 失效的代碼

class TestService {
    void a() { 
      this.b();
    }
	
    @Async
    void b(){}
}

正常的代碼

class TestService {
    void a(){ 
       BService.b();
    }
}

class BService() {
    @Async
    void b(){}
}

這個(gè)時(shí)候我們可能會(huì)想到AopContext.currentProxy(),這樣就可以在同一個(gè)方法里面調(diào)用了

class TestService {
	
   TestService getSelf() {
      return (TestService)AopContext.currentProxy();
   }
	
    void a() { 
      getSelf().b();
    }
	
    @Async
    void b(){}
}

在這里可能會(huì)拋出以下的異常,具體的原因及解決思路請參考這篇文章

java.lang.IllegalStateException: Cannot find current proxy:
Set 'exposeProxy' property on Advised to 'true' to make it available.

三、接下來了解一下@Async使用的線程池
@Async異步方法默認(rèn)使用Spring創(chuàng)建ThreadPoolTaskExecutor(參考TaskExecutionAutoConfiguration),其中默認(rèn)核心線程數(shù)為8,默認(rèn)最大隊(duì)列和默認(rèn)最大線程數(shù)都是Integer.MAX_VALUE。創(chuàng)建新線程的條件是隊(duì)列填滿時(shí),而這樣的配置隊(duì)列永遠(yuǎn)不會(huì)填滿,如果有@Async注解標(biāo)注的方法長期占用線程(比如HTTP長連接等待獲取結(jié)果),在核心8個(gè)線程數(shù)占用滿了之后,新的調(diào)用就會(huì)進(jìn)入隊(duì)列, 外部表現(xiàn)為沒有執(zhí)行。
我們可以自定義一個(gè)線程池,線程數(shù)的設(shè)定需要考慮一下要執(zhí)行的任務(wù)是IO密集型任務(wù),還是CPU密集型任務(wù)。對于CPU密集型任務(wù),如CPU核數(shù)+1;對于IO密集型任務(wù),由于IO密集型任務(wù)線程并不是一直在執(zhí)行任務(wù),則應(yīng)配置盡可能多的線程,如CPU核數(shù)*2。
接下來給出一個(gè)IO密集型任務(wù)的線程池配置代碼

@Configuration
public class ThreadPoolConfig {

    /**
     * 核心線程數(shù)
     */
    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;

    /**
     * 最大線程數(shù)
     */
    private static final int MAX_POOL_SIZE = CORE_POOL_SIZE * 4 < 256 ? 256 : CORE_POOL_SIZE * 4;

    /**
     * 允許線程空閑時(shí)間(單位為秒)
     */
    private static final int KEEP_ALIVE_TIME = 10;

    /**
     * 緩沖隊(duì)列數(shù)
     */
    private static final int QUEUE_CAPACITY = 200;

    /**
     * 線程池中任務(wù)的等待時(shí)間,如果超過這個(gè)時(shí)候還沒有銷毀就強(qiáng)制銷毀
     */
    private static final int AWAIT_TERMINATION = 60;

    /**
     * 用來設(shè)置線程池關(guān)閉的時(shí)候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean
     */
    private static final Boolean WAIT_FOR_TASKS_TO_COMPLETE_ON_SHUTDOWN = true;

    /**
     * 線程池名前綴
     */
    private static final String THREAD_NAME_PREFIX = "Spider-ThreadPool-";


    @Bean("spiderTaskExecutor")
    public ThreadPoolTaskExecutor spiderTaskExecutor () {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        taskExecutor.setKeepAliveSeconds(KEEP_ALIVE_TIME);
        taskExecutor.setQueueCapacity(QUEUE_CAPACITY);
        taskExecutor.setThreadNamePrefix(THREAD_NAME_PREFIX);
        taskExecutor.setWaitForTasksToCompleteOnShutdown(WAIT_FOR_TASKS_TO_COMPLETE_ON_SHUTDOWN);
        taskExecutor.setAwaitTerminationSeconds(AWAIT_TERMINATION);
        /**
         * 拒絕策略 => 當(dāng)pool已經(jīng)達(dá)到max size的時(shí)候,如何處理新任務(wù)
         * CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是由調(diào)用者所在的線程來執(zhí)行
         * AbortPolicy:直接拋出異常,這是默認(rèn)策略;
         * DiscardOldestPolicy:丟棄阻塞隊(duì)列中靠最前的任務(wù),并執(zhí)行當(dāng)前任務(wù);
         * DiscardPolicy:直接丟棄任務(wù);
         */
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }

}

線程池的使用

@Async("spiderTaskExecutor")

最后補(bǔ)充一些知識,要合理的控制線程數(shù)(比如采集訂單信息的同時(shí)要采集訂單詳情和文章信息,訂單詳情和文章信息可以合并在一個(gè)線程中處理),不要濫用。需要考慮什么時(shí)候使用MQ,什么時(shí)候開啟線程異步處理。推薦一個(gè)分析jstack文件的工具,IBM Thread and Monitor Dump Analyzer for Java,分析一下正在運(yùn)行、發(fā)生死鎖、等待、阻塞的線程。

以上是“@Async怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)頁題目:@Async怎么用
分享URL:http://jinyejixie.com/article34/poedse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、自適應(yīng)網(wǎng)站、ChatGPT、服務(wù)器托管、響應(yīng)式網(wǎng)站、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
太白县| 鹤山市| 商城县| 武安市| 隆子县| 高淳县| 河南省| 琼结县| 额敏县| 壶关县| 巴林左旗| 大关县| 本溪| 多伦县| 台东县| 哈密市| 大关县| 无棣县| 石台县| 玉龙| 湟中县| 建水县| 垫江县| 庐江县| 三都| 光山县| 亚东县| 连城县| 天峻县| 平山县| 鄢陵县| 库尔勒市| 青冈县| 台东县| 高邑县| 石渠县| 循化| 东丽区| 东乌珠穆沁旗| 华池县| 万山特区|