網(wǎng)站開發(fā)產(chǎn)品經(jīng)理招聘雞西seo
在 Spring 中,@Async 注解用于將方法標記為異步執(zhí)行的方法。當使用 @Async 注解時,該方法將在單獨的線程中執(zhí)行,而不會阻塞當前線程。這使得方法可以在后臺執(zhí)行,而不會影響主線程的執(zhí)行。
在您提供的代碼示例中,a1() 和 a2() 方法都被標記為 @Async,意味著它們將以異步方式執(zhí)行。這意味著當調用這些方法時,它們將會在單獨的線程中執(zhí)行,而不會等待方法執(zhí)行完成。
如果不使用 @Async 注解,則方法將會以同步方式執(zhí)行。也就是說,當調用這些方法時,程序將會阻塞在方法執(zhí)行處,直到方法執(zhí)行完成才會繼續(xù)執(zhí)行后續(xù)代碼。
因此,加上 @Async 注解的方法能夠實現(xiàn)并發(fā)執(zhí)行,而不加 @Async 注解的方法則會按照順序逐個執(zhí)行。根據(jù)您的代碼示例,加上 @Async 注解后,a1() 和 a2() 方法將會同時啟動并發(fā)執(zhí)行,而不會相互阻塞。
需要注意的是,使用 @Async 注解需要配置一個任務執(zhí)行器(Task Executor)來處理異步方法的調用。如果在 Spring Boot 項目中使用 @EnableAsync 注解來啟用異步支持,Spring 將會自動配置默認的任務執(zhí)行器。如果未配置任務執(zhí)行器,則異步方法將在調用線程中執(zhí)行,而不會啟動新的線程來執(zhí)行。
配置任務執(zhí)行器(Task Executor)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;@Configuration
@EnableAsync
public class AsyncConfig {// 配置任務執(zhí)行器@Bean(name = "taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 設置核心線程數(shù)executor.setCorePoolSize(10);// 設置最大線程數(shù)executor.setMaxPoolSize(20);// 設置隊列容量executor.setQueueCapacity(100);// 設置線程活躍時間(秒)executor.setKeepAliveSeconds(60);// 設置線程名稱前綴executor.setThreadNamePrefix("Async-");// 設置拒絕策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 初始化線程池executor.initialize();return executor;}
}
設置核心線程數(shù)、設置最大線程數(shù)和設置隊列容量是線程池中的一些重要參數(shù)。
- 核心線程數(shù)(Core Thread Pool Size):指的是線程池中保持的線程數(shù)量。即使這些線程處于空閑狀態(tài),它們也會一直存在于線程池中,以備接收新的任務。當線程池中的線程數(shù)量小于核心線程數(shù)時,新的任務將會創(chuàng)建新的線程來執(zhí)行。
- 最大線程數(shù)(Maximum Pool Size):指的是線程池中允許的最大線程數(shù)量。當線程池中的線程數(shù)量達到核心線程數(shù)時,如果還有新的任務需要執(zhí)行,線程池將會再創(chuàng)建新的線程,直到達到最大線程數(shù)為止。當線程池中的線程數(shù)量達到最大值且隊列也已滿時,則會拒絕執(zhí)行新的任務。
- 隊列容量(Queue Capacity):指的是線程池中任務隊列可以容納的最大任務數(shù)量。當線程池中的線程數(shù)量達到核心線程數(shù)時,如果還有新的任務需要執(zhí)行,線程池將會將這些任務添加到任務隊列中。如果任務隊列已滿,則會根據(jù)線程池的策略來處理這些被拒絕的任務。
這些參數(shù)的設置應該根據(jù)應用程序的需求和系統(tǒng)的資源來確定。過小的核心線程數(shù)和隊列容量可能導致任務長時間排隊等待執(zhí)行,而過大的最大線程數(shù)則可能會消耗過多的系統(tǒng)資源。
定時任務A1
@Component
@EnableScheduling
public class A1 {@Async("taskExecutor")@Scheduled(cron = "0 0/1 * * * ?")public void a1(){for (int i = 0; i < 1000; i++) {System.out.println("我是a1");}}
}
定時任務A2
@Component
@EnableScheduling
public class A2 {@Async("taskExecutor")@Scheduled(cron = "0 0/1 * * * ?")public void a2(){for (int i = 0; i < 1000; i++) {System.out.println("我是a2");}}
}
加了@Async輸出結果大概如下
A1和A2多線程交替執(zhí)行,并發(fā)
我是a1
我是a2
我是a1
我是a2
我是a1
我是a2
我是a1
我是a2
我是a1
我是a2
...
不加@Async輸出結果大概如下
先執(zhí)行完A1才會去執(zhí)行A2,按順序執(zhí)行,阻塞
我是a1
我是a1
我是a1
我是a1
我是a1
我是a2
我是a2
我是a2
我是a2
我是a2
...
當涉及到設置線程池的核心線程數(shù)、最大線程數(shù)和隊列容量時,需要根據(jù)具體的應用場景和需求來確定。下面是一些示例:
場景一:Web 服務器請求處理
假設有一個 Web 服務器,需要處理大量的并發(fā)請求。在這種情況下,可以考慮以下設置:
- 核心線程數(shù):根據(jù)服務器的負載和處理能力,設置一個適當?shù)暮诵木€程數(shù),例如設置為 CPU 核心數(shù)的兩倍。
- 最大線程數(shù):根據(jù)服務器的資源和性能,設置一個合理的最大線程數(shù),例如設置為 CPU 核心數(shù)的四倍。
- 隊列容量:如果服務器的處理能力超過了核心線程數(shù)和最大線程數(shù),可以設置一個適當?shù)年犃腥萘?#xff0c;以便將超出處理能力的請求暫存到隊列中,例如使用一個有界隊列。
場景二:后臺任務處理
假設有一個后臺任務需要處理大量的耗時操作,比如文件處理、數(shù)據(jù)導入等。在這種情況下,可以考慮以下設置:
- 核心線程數(shù):根據(jù)系統(tǒng)的負載和任務的數(shù)量,設置一個適當?shù)暮诵木€程數(shù),例如設置為固定值,如10個線程。
- 最大線程數(shù):根據(jù)系統(tǒng)的資源和性能,設置一個合理的最大線程數(shù),例如設置為20個線程。
- 隊列容量:如果任務數(shù)量超過了核心線程數(shù)和最大線程數(shù),可以設置一個適當?shù)年犃腥萘?#xff0c;以便將超出處理能力的任務暫存到隊列中,例如使用一個無界隊列。
需要根據(jù)具體的應用場景和系統(tǒng)要求來靈活調整這些參數(shù)。合理設置這些參數(shù)可以提高系統(tǒng)的性能和資源利用率,避免因為線程過多或過少導致的性能問題或資源浪費。