🔄Update: 基于 Async 实现线程池
This commit is contained in:
@@ -1,5 +1,18 @@
|
|||||||
# 使用 `@Async` 实现线程池
|
# 使用 `@Async` 实现线程池
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[调用者调用异步方法] --> B[Spring AOP 代理拦截方法调用]
|
||||||
|
B --> C{方法是否为 @Async?}
|
||||||
|
C -->|是| D[封装为 FutureTask 或 Runnable]
|
||||||
|
C -->|否| E[按正常方式执行]
|
||||||
|
D --> F[提交到线程池 TaskExecutor]
|
||||||
|
F --> G[线程池分配一个线程]
|
||||||
|
G --> H[JVM 创建线程并执行任务]
|
||||||
|
H --> I[任务执行完毕,返回结果]
|
||||||
|
I --> J[调用者通过 Future 获取结果]
|
||||||
|
```
|
||||||
|
|
||||||
## 前置知识
|
## 前置知识
|
||||||
|
|
||||||
### **`@Async`**
|
### **`@Async`**
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package cn.hezhaohui.threadpool.conifg;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步配置类
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableAsync
|
||||||
|
public class AsyncConfig {
|
||||||
|
|
||||||
|
@Bean(name = "customThreadPool")
|
||||||
|
public Executor customThreadPool() {
|
||||||
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||||
|
executor.setCorePoolSize(5);
|
||||||
|
executor.setMaxPoolSize(10);
|
||||||
|
executor.setQueueCapacity(100);
|
||||||
|
executor.setThreadNamePrefix("Custom-Async-");
|
||||||
|
executor.initialize();
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package cn.hezhaohui.threadpool.service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class AsyncService {
|
||||||
|
|
||||||
|
@Async("customThreadPool")
|
||||||
|
public void asyncPrint() {
|
||||||
|
String id = UUID.randomUUID().toString().substring(0, 5);
|
||||||
|
int sleepSeconds = new Random().nextInt(15);
|
||||||
|
log.info("[Thread {}] Called, waiting {} seconds", id, sleepSeconds);
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepSeconds * 1000L);
|
||||||
|
log.info("[Thread {}] Wait completed after {} seconds", id, sleepSeconds);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("[Thread {}] Interrupted during wait", id, e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async("customThreadPool")
|
||||||
|
public void asyncPrint(CountDownLatch latch) {
|
||||||
|
String id = UUID.randomUUID().toString().substring(0, 5);
|
||||||
|
int sleepSeconds = new Random().nextInt(15);
|
||||||
|
log.info("[Thread {}] ⚠️ Called, waiting {} seconds", id, sleepSeconds);
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepSeconds * 1000L);
|
||||||
|
log.info("[Thread {}] ✅ Wait completed after {} seconds", id, sleepSeconds);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("[Thread {}] Interrupted during wait", id, e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
} finally {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package cn.hezhaohui.threadpool.service;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@Slf4j
|
||||||
|
class AsyncServiceTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AsyncService asyncService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void asyncPrint() throws InterruptedException {
|
||||||
|
CountDownLatch latch = new CountDownLatch(15);
|
||||||
|
for (int i = 0; i < 200; i++) {
|
||||||
|
asyncService.asyncPrint(latch);
|
||||||
|
}
|
||||||
|
log.info("\n[+++ All Tasks Commited +++]\n");
|
||||||
|
latch.await();
|
||||||
|
log.info("\n[=== All Tasks Completed ===]\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user