1.異步任務
在項目開發中,針對耗時業務邏輯,往往採用多線程來處理此任務。在Spring中使用異步任務極爲方便,只需要一個@Async註解即可將任務加入線程池運行,極大的提高了開發效率。
1.1 使用異步任務
默認情況下,無需做任何額外配置,只需要以下兩步便可使用SpringBoot的異步任務:
- 在啓動類加上@EnableAsync註解,開啓註解使用異步任務的功能;
- 在想要異步執行的方法前加上@Async註解,同時需要將該方法所在類注入Spring IOC容器,該方法在被調用時將異步執行。
啓動類代碼:
@SpringBootApplication
@EnableAsync
public class SpringBootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTaskApplication.class, args);
}
}
異步任務代碼如下:
@Service
public class AsyncService {
@Async
public void ProtocolInterpreter()
{
try {
//模擬耗時操作
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":協議解析完成");
}
}
調用異步任務:
@RestController
public class HelloController {
@Autowired
AsyncService asyncService;
@GetMapping("/hello")
public String hello() {
asyncService.ProtocolInterpreter();
asyncService.ProtocolInterpreter();
asyncService.ProtocolInterpreter();
return "success";
}
}
在瀏覽器訪問地址http://localhost:8080/hello,success會被立刻返回
控制檯打印:
1.2 配置異步任務
默認情況下,我們無需對SpringBoot的異步任務做任何特殊配置便可使用。但在一些要求比較高的應用中,SpringBoot的默認配置並不能滿足我們的需求。這就需要我們手動配置了:
spring:
task:
execution:
#配置線程池名稱前綴
thread-name-prefix: async-task-
pool:
#配置核心線程數,即線程池創建時的初始化大小,SpringBoot2.2默認值爲8
core-size: 10
#配置最大線程數,SpringBoot2.2默認值爲2147483647
max-size: 100
#配置緩衝隊列數,用來存放待執行的任務,SpringBoot2.2默認值爲2147483647
#當待執行的線程數超過此隊列大小時,Spring會將線程數增加,上限爲所配置的最大線程數
queue-capacity: 1000
#配置線程最大空閒時間,線程空閒時間超過此時間,將被回收,SpringBoot2.2默認值爲60(s)
keep-alive: 20s
上面列出的配置文件中,我們做了以下配置:
- thread-name-prefix: 配置線程名稱前綴,默認爲task-
- pool.core-size: 配置線程池初始化時創建的線程個數
- pool.max-size: 配置線程池最大線程數
- pool.queue-capacity: 配置線程緩衝隊列大小,如果緩衝隊列達到了上限,Spring會將線程數增加,上限爲pool.max-size
- pool.keep-alive: 配置線程最大空閒時間,超過此時間,線程將會被回收
2.定時任務
在實際項目中往往還需要定時任務,比如定時清理日誌、定時備份數據庫中的數據、定時統計數據做報表等等。下面就來看一看SpringBoot的定時任務怎麼用吧。
2.1 使用定時任務
只需要以下兩個步驟,便可使用SpringBoot的定時任務:
- 在啓動類添加@EnableScheduling註解,開啓註解使用定時任務的功能
- 在要定時執行的方法前加上@Scheduled註解,同時需要將該方法所在類注入Spring IOC容器
啓動類代碼:
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class SpringBootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTaskApplication.class, args);
}
}
定時任務代碼如下:
@Service
public class ScheduledService {
@Scheduled(cron = "*/1 * * * * *")
public void tellTime()
{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("currentTime:" + simpleDateFormat.format(new Date()));
}
}
上面這段代碼1s執行一次,作用是打印當前時間。
2.2 cron表達式詳解
格式:cron = " 秒 分 時 日 月 星期幾 "
屬性 | 取值範圍 | 特殊符號 |
---|---|---|
秒 | 0-59 | , - * / |
分 | 0-59 | , - * / |
時 | 0-59 | , - * / |
日 | 1-31 | , - * / ? L W C |
月 | 1-12 | , - * / |
星期幾 | 0 - 7(0、7都代表週日) | , - * / ? L C # |
特殊符號解釋
符號 | 含義 |
---|---|
, | 以逗號分割指定多個值 |
- | 區間 |
* | 任意 |
/ | 步長 |
? | 日/星期衝突匹配。比如: * * * ? * 1 每週1執行,則日用 ? 不能用 * , 不是每一天都是週一; * * * 2 * ? 每月2號,則星期不能用* |
L | 最後 |
W | 工作日 |
# | 這個月的第幾個星期幾 如3#2代表這個月的第2個星期三 |
用法舉例:
表達式 | 含義 |
---|---|
*/1 * * * * * | 每1s執行一次 |
* 1-5 * * * * | 第1分鐘到第5分鐘觸發,觸發時每秒執行一次 |
0 1-5 * * * * | 第1分鐘到第5分鐘的第0秒分別觸發一次 |
0 */2 * * * * | 每隔2分鐘執行一次 |
0 0 13 * * * | 每天13:00:00執行一次 |
* 1-5 * * * * | 第1分鐘到第5分鐘觸發,觸發時一直執行 |
0 0-5 14 * * * | 在每天下午2點到下午2:05期間的每1分鐘觸發一次 |
0 0 23 L * ? | 每月最後一天23:00:00執行一次 |
0 30 17 LW * ? | 每個月最後一個工作日的17:30:00觸發任務一次 |
2.3 配置定時任務
SpringBoot在默認情況下使用一個線程來處理定時任務,其實這已經滿足了絕大多數的需求。如果想要更改,可通過設置spring.task.scheduling.pool.size屬性:
spring:
task:
scheduling:
thread-name-prefix: my-scheduling-
pool:
size: 3
關於SpringBoot的異步任務、定時任務就講解到這裏,歡迎大家在評論區留言討論。