spring boot自定義執行緒池進行非同步呼叫

2021-10-08 22:38:58 字數 4236 閱讀 9076

大型超市裡,通常都不止乙個收銀台,因為這樣可以提高效率,設想一下,如果某一天,其他的收銀員都請假了,只剩下乙個收銀台,看著那漫長的排隊大軍,是不是很捉急,很無奈。這就是非同步存在的意義了。

如果直接使用 @async,那麼預設就是使用******asynctaskexecutor執行緒池,由於 ******asynctaskexecutor 不限制併發執行緒而且不重用執行緒,那麼直接使用是有風險的,所以本章直接介紹通過自定義執行緒池來使用 @async 達到非同步呼叫的目的。

@enableasync

@configuration

public

class

threadpoolconfig

}

@enableasync註解主要是為了掃瞄範圍包下的所有@async註解

@component

public

class

asynctask

catch

(interruptedexception e)

system.out.

println

("task1 執行結束,耗時:"

+(system.

currenttimemillis()

- starttime));

}/**

* task 1

*/@async

("taskexecutor"

)public

void

task2()

catch

(interruptedexception e)

system.out.

println

("task2 執行結束,耗時:"

+(system.

currenttimemillis()

- starttime));

}}

@restcontroller

public

class

asynccontroller

}

列印結果:

test 開始執行

test 執行結束,耗時:6

task1 開始執行

task2 開始執行

task1 執行結束,耗時:1000

task2 執行結束,耗時:1000

以上的 task1 和 task2 任務是沒有返回值,如果碰到需要獲取任務結果怎麼辦,這時候就可以用到 future 了。

先給 task1 和 task2 新增返回值:

/**

* task 1

*/@async

("taskexecutor"

)public future

task1()

catch

(interruptedexception e)

system.out.

println

("task1 執行結束,耗時:"

+(system.

currenttimemillis()

- starttime));

return

newasyncresult

<

>

("task1 success");

}/**

* task 2

*/@async

("taskexecutor"

)public future

task2()

catch

(interruptedexception e)

system.out.

println

("task2 執行結束,耗時:"

+(system.

currenttimemillis()

- starttime));

return

newasyncresult

<

>

("task2 success");

}

然後進行呼叫,並獲取結果:

("/async"

)public

void

test()

throws executionexception, interruptedexception

列印結果如下:

test 開始執行

task1 開始執行

task2 開始執行

task1 執行結束,耗時:1001

task2 執行結束,耗時:1001

test 執行結果,result1:task1 success, result2:task2 success

test 執行結束,耗時:1016

可以看到 task1 和 task2 是非同步執行的,並且成功獲取到返回結果。

如果將在非同步任務類中直接呼叫 @async 修飾的方法,那麼非同步呼叫將會失效。

舉個栗子

在 asynctask 類中直接呼叫 task1 和 task2 方法:

public

void

test()

然後在 asynccontroller 中呼叫 test 方法:

("/async"

)public

void

test()

列印結果如下:

test 開始執行

task1 開始執行

task1 執行結束,耗時:1000

task2 開始執行

task2 執行結束,耗時:1001

test 執行結束,耗時:2001

可以明顯看出,task1 和 task2 不是非同步執行的。原因就是呼叫 task1 和 task2 方法的是 asynctask 物件本身,而不是 spring 啟動的時候為其建立的**物件,沒有經過 spring 容器。如果要解決這個問題,就按照這個思路,建立乙個**物件即可。

@component

public

class

asynctask

/** * task 1

*/@async

("taskexecutor"

)public future

task1()

catch

(interruptedexception e)

system.out.

println

("task1 執行結束,耗時:"

+(system.

currenttimemillis()

- starttime));

return

newasyncresult

<

>

("task1 success");

}/**

* task 2

*/@async

("taskexecutor"

)public future

task2()

catch

(interruptedexception e)

system.out.

println

("task2 執行結束,耗時:"

+(system.

currenttimemillis()

- starttime));

return

newasyncresult

<

>

("task2 success");

}}

呼叫方法:

("/async"

)public

void

test()

throws executionexception, interruptedexception

列印結果:

test 開始執行

test 開始執行

test 執行結束,耗時:6

test 執行結束,耗時:0

task1 開始執行

task2 開始執行

task1 執行結束,耗時:1000

task2 執行結束,耗時:1000

可以看到 task1 和 task2 是非同步執行的,該思路是生效的。

框架 SpringBoot中自定義執行緒池

springboot中對執行緒池的自定義分為兩種 修改預設的執行緒池 建立新的自定義執行緒池 修改預設的執行緒池,需要建立配置類 加入兩個註解 enableasync開啟非同步執行功能 configurationspring配置類 實現asyncconfigurer介面,並實現兩個方法 public...

自定義Spring Boot裝配

spring boot自動配置會嘗試根據新增的jar依賴項自動配置spring應用程式。使用 componentscan 查詢您的bean 和使用 autowired 進行建構函式注入 自動配置類使用 conditionalonclass和 conditionalo singbean注釋,condi...

springboot自定義事務

1.在springboot專案中service的實現類可以通過註解 transactional新增事務 1.1 如果在service層用了try catch,在catch裡面再丟擲乙個 runtimeexception異常,這樣出了異常才會回滾 1.2你還可以直接在catch後面寫一句回滾 tran...