🔄Update: 基于 Async 实现线程池
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
# 使用 `@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`**
|
||||
|
||||
@@ -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