SpringBoot異步處理@Async深度解析:從基礎到高階實戰

一、異步編程基礎概念

1.1 同步 vs 異步

特性同步異步
執行方式順序執行,阻塞調用非阻塞,調用后立即返回
線程使用單線程完成所有任務多線程并行處理
響應性較差,需等待前任務完成較好,可立即響應新請求
復雜度簡單直觀較復雜,需處理線程安全
適用場景簡單流程,短時間任務IO密集型,長時間任務

通俗理解:同步就像在銀行柜臺排隊辦理業務,必須等前面的人辦完才能輪到你;異步則像取號后可以坐著玩手機,等叫號時再去辦理。

1.2 為什么要使用異步

  • 提高吞吐量:服務器能同時處理更多請求
  • 增強用戶體驗:避免用戶長時間等待
  • 資源優化:合理利用系統資源,避免阻塞主線程
  • 解耦:將耗時操作與主流程分離

1.3 Java中的異步編程方式

// 1. 傳統Thread方式
new Thread(() -> {// 異步任務
}).start();// 2. Future模式
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {Thread.sleep(1000);return "Result";
});// 3. CompletableFuture (Java8+)
CompletableFuture.supplyAsync(() -> {// 異步任務return "Result";
}).thenAccept(result -> {// 處理結果
});// 4. Spring @Async (本文重點)
@Async
public void asyncMethod() {// 異步方法體
}

二、@Async基礎使用

2.1 啟用@Async支持

步驟1:在Spring Boot主類或配置類上添加@EnableAsync

@SpringBootApplication
@EnableAsync  // 啟用異步支持
public class AsyncApplication {public static void main(String[] args) {SpringApplication.run(AsyncApplication.class, args);}
}

步驟2:創建異步服務類

@Service
public class EmailService {// 無返回值異步方法@Asyncpublic void sendEmail(String to, String content) {// 模擬郵件發送耗時try {Thread.sleep(3000);System.out.println("郵件已發送至: " + to + ", 內容: " + content);} catch (InterruptedException e) {e.printStackTrace();}}// 有返回值異步方法@Asyncpublic Future<String> sendEmailWithResult(String to, String content) {try {Thread.sleep(3000);String result = "郵件已發送至: " + to;return new AsyncResult<>(result);} catch (InterruptedException e) {return new AsyncResult<>("發送失敗");}}
}

2.2 調用異步方法

@RestController
@RequestMapping("/api/email")
public class EmailController {@Autowiredprivate EmailService emailService;@GetMapping("/send")public String sendEmail() {long start = System.currentTimeMillis();// 調用異步方法emailService.sendEmail("user@example.com", "您的訂單已創建");long elapsed = System.currentTimeMillis() - start;return "請求已處理,耗時: " + elapsed + "ms"; // 立即返回,不會等待郵件發送完成}@GetMapping("/send-with-result")public String sendEmailWithResult() throws Exception {Future<String> future = emailService.sendEmailWithResult("user@example.com", "訂單詳情");// 可以在這里做其他事情// 當需要結果時(阻塞等待)String result = future.get();return "處理結果: " + result;}
}

2.3 @Async方法限制

  1. 必須public修飾:因為基于Spring AOP實現
  2. 同類調用無效this.asyncMethod()不會異步執行
  3. 返回值限制
    • void
    • Future及其子類(如AsyncResult)
    • CompletableFuture (Spring 4.2+)
    • ListenableFuture (Spring 4.2+)

三、線程池配置詳解

3.1 默認線程池問題

Spring默認使用SimpleAsyncTaskExecutor,它不重用線程,每次調用都創建新線程,生產環境不推薦使用。

3.2 自定義線程池配置

方式1:配置類方式(推薦)

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 核心線程數:線程池創建時初始化的線程數executor.setCorePoolSize(5);// 最大線程數:線程池最大的線程數,只有在緩沖隊列滿了之后才會申請超過核心線程數的線程executor.setMaxPoolSize(10);// 緩沖隊列:用來緩沖執行任務的隊列executor.setQueueCapacity(50);// 線程名前綴executor.setThreadNamePrefix("Async-Executor-");// 線程池關閉時等待所有任務完成executor.setWaitForTasksToCompleteOnShutdown(true);// 等待時間executor.setAwaitTerminationSeconds(60);// 拒絕策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new CustomAsyncExceptionHandler();}
}// 自定義異常處理器
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {@Overridepublic void handleUncaughtException(Throwable ex, Method method, Object... params) {System.err.println("異步任務異常 - 方法: " + method.getName());System.err.println("異常信息: " + ex.getMessage());// 這里可以添加自定義處理邏輯,如記錄日志、發送告警等}
}

方式2:使用@Bean定義多個線程池

@Configuration
public class TaskExecutorConfig {@Bean(name = "emailExecutor")public Executor emailTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(3);executor.setMaxPoolSize(5);executor.setQueueCapacity(30);executor.setThreadNamePrefix("Email-Executor-");executor.initialize();return executor;}@Bean(name = "reportExecutor")public Executor reportTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(2);executor.setMaxPoolSize(4);executor.setQueueCapacity(20);executor.setThreadNamePrefix("Report-Executor-");executor.initialize();return executor;}
}

使用指定線程池:

@Async("emailExecutor")
public void sendEmail(String to) { /*...*/ }@Async("reportExecutor")
public void generateReport() { /*...*/ }

3.3 線程池參數詳解

參數名說明推薦設置建議
corePoolSize核心線程數,即使空閑也不會被回收CPU密集型:CPU核數+1
IO密集型:2*CPU核數
maxPoolSize最大線程數,當隊列滿時才會創建新線程直到此值建議為核心線程數的2-3倍
queueCapacity任務隊列容量,超過核心線程數的任務會進入隊列根據業務量調整,太大可能導致OOM
keepAliveSeconds非核心線程空閑存活時間(秒)60-300秒
threadNamePrefix線程名前綴,便于監控和日志追蹤建議按業務命名,如"Order-Async-"
allowCoreThreadTimeOut是否允許核心線程超時退出默認false,長時間空閑應用可設為true
waitForTasksToCompleteOnShutdown應用關閉時是否等待異步任務完成生產環境建議true
awaitTerminationSeconds等待任務完成的超時時間根據業務最長執行時間設置
rejectedExecutionHandler拒絕策略,當線程池和隊列都滿時的處理方式根據業務需求選擇

拒絕策略選項

  • AbortPolicy:默認,直接拋出RejectedExecutionException
  • CallerRunsPolicy:由調用者線程執行該任務
  • DiscardPolicy:直接丟棄任務
  • DiscardOldestPolicy:丟棄隊列中最老的任務并重試

3.4 線程池監控

@Service
public class ThreadPoolMonitor {@Autowiredprivate ThreadPoolTaskExecutor emailExecutor;@Scheduled(fixedRate = 5000)  // 每5秒監控一次public void monitor() {System.out.println("=== 線程池監控 ===");System.out.println("當前線程數: " + emailExecutor.getPoolSize());System.out.println("活躍線程數: " + emailExecutor.getActiveCount());System.out.println("完成任務數: " + emailExecutor.getCompletedTaskCount());System.out.println("隊列剩余容量: " + emailExecutor.getThreadPoolExecutor().getQueue().remainingCapacity());}
}

四、@Async高級特性

4.1 返回值處理

1. Future模式

@Async
public Future<String> processData(String input) {// 模擬處理耗時try {Thread.sleep(2000);return new AsyncResult<>("處理完成: " + input.toUpperCase());} catch (InterruptedException e) {Thread.currentThread().interrupt();return new AsyncResult<>("處理中斷");}
}// 調用方
Future<String> future = service.processData("hello");
// 可以做其他事情...
String result = future.get(3, TimeUnit.SECONDS); // 帶超時的等待

2. CompletableFuture (Java8+)

@Async
public CompletableFuture<String> fetchData(String param) {return CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);return "Data for " + param;} catch (InterruptedException e) {throw new RuntimeException(e);}});
}// 鏈式調用
service.fetchData("user123").thenApply(String::toUpperCase).thenAccept(System.out::println).exceptionally(ex -> {System.err.println("Error: " + ex.getMessage());return null;});

4.2 基于條件的異步執行

1. 使用Spring Expression Language (SpEL)

@Async("#{systemProperties['async.enabled'] ? 'emailExecutor' : 'syncExecutor'}")
public void conditionalAsync() {// 根據系統屬性決定使用哪個執行器
}

2. 基于配置的開關

@Async
@ConditionalOnProperty(name = "app.async.enabled", havingValue = "true")
public void configBasedAsync() {// 當app.async.enabled=true時才異步執行
}

4.3 事務處理

異步方法與事務的特殊關系:

  1. 事務邊界@Async方法會在新線程中執行,與原方法不在同一事務中
  2. 傳播行為:需要在異步方法上單獨聲明@Transactional
@Async
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void asyncWithTransaction() {// 這個方法會在新事務中執行userRepository.save(new User("AsyncUser"));// 如果發生異常,只會回滾當前方法內的操作
}

4.4 組合異步操作

場景:需要等待多個異步任務全部完成

@Async
public CompletableFuture<String> fetchUserInfo(String userId) {// 模擬獲取用戶信息return CompletableFuture.completedFuture("UserInfo-" + userId);
}@Async
public CompletableFuture<String> fetchOrderInfo(String userId) {// 模擬獲取訂單信息return CompletableFuture.completedFuture("OrderInfo-" + userId);
}// 組合多個異步任務
public CompletableFuture<Void> combineAsyncTasks(String userId) {return CompletableFuture.allOf(fetchUserInfo(userId),fetchOrderInfo(userId)).thenRun(() -> {// 所有任務完成后的處理System.out.println("所有異步任務已完成");});
}

五、異常處理機制

5.1 異常處理方式對比

處理方式適用場景優點缺點
AsyncUncaughtExceptionHandler處理void返回類型的異步方法異常集中處理,統一管理無法獲取方法返回值
Future.get()處理有返回值的異步方法異常可以獲取具體異常信息需要手動調用get()
CompletableFuture.exceptionallyJava8+的優雅異常處理方式鏈式調用,代碼簡潔僅適用于CompletableFuture

5.2 實踐示例

1. 全局異常處理器

public class GlobalAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(GlobalAsyncExceptionHandler.class);@Overridepublic void handleUncaughtException(Throwable ex, Method method, Object... params) {logger.error("異步任務異常 - 方法: {}, 參數: {}", method.getName(), Arrays.toString(params), ex);// 可以根據異常類型進行不同處理if (ex instanceof BusinessException) {// 業務異常處理sendAlert("業務異常警報: " + ex.getMessage());} else if (ex instanceof TimeoutException) {// 超時處理retryTask(method, params);}}private void sendAlert(String message) { /*...*/ }private void retryTask(Method method, Object... params) { /*...*/ }
}

2. Future方式的異常處理

@Async
public Future<String> asyncTaskWithException() {try {// 業務邏輯if (someCondition) {throw new BusinessException("業務異常");}return new AsyncResult<>("成功");} catch (BusinessException e) {return new AsyncResult<>("失敗: " + e.getMessage());}
}// 調用方處理
Future<String> future = service.asyncTaskWithException();
try {String result = future.get();if (result.startsWith("失敗")) {// 處理失敗情況}
} catch (ExecutionException e) {// 處理執行時異常
}

3. CompletableFuture的異常處理

@Async
public CompletableFuture<String> asyncProcess(String input) {return CompletableFuture.supplyAsync(() -> {if (input == null) {throw new IllegalArgumentException("輸入不能為空");}return "處理結果: " + input.toUpperCase();});
}// 調用方處理
service.asyncProcess(null).exceptionally(ex -> {System.err.println("發生異常: " + ex.getMessage());return "默認返回值";}).thenAccept(result -> {System.out.println("最終結果: " + result);});

六、性能優化與最佳實踐

6.1 性能優化建議

  1. 線程池參數調優

    • 根據業務類型調整線程池大小
    • 監控線程池狀態動態調整參數
    • 使用有界隊列防止OOM
  2. 避免長時間阻塞

    • 異步方法內避免同步阻塞操作
    • 使用帶超時的阻塞調用
  3. 資源清理

    • 確保異步方法正確釋放資源
    • 使用try-with-resources管理資源
  4. 上下文傳遞

    • 注意ThreadLocal變量在異步線程中的傳遞問題
    • 使用TaskDecorator傳遞上下文
executor.setTaskDecorator(new ContextCopyingDecorator());public class ContextCopyingDecorator implements TaskDecorator {@Overridepublic Runnable decorate(Runnable runnable) {// 獲取當前線程的上下文RequestAttributes context = RequestContextHolder.currentRequestAttributes();return () -> {try {// 在新線程中設置上下文RequestContextHolder.setRequestAttributes(context);runnable.run();} finally {RequestContextHolder.resetRequestAttributes();}};}
}

6.2 最佳實踐清單

  1. 命名規范

    • 異步方法名以Async后綴標識,如sendEmailAsync
    • 線程池按業務命名,如orderTaskExecutor
  2. 日志記錄

    • 記錄異步任務開始/結束時間
    • 為異步線程設置可追蹤的上下文ID
@Async
public void asyncWithLogging() {String traceId = UUID.randomUUID().toString();MDC.put("traceId", traceId);try {log.info("異步任務開始");// 業務邏輯log.info("異步任務完成");} finally {MDC.clear();}
}
  1. 防御性編程

    • 檢查異步方法參數有效性
    • 添加合理的超時控制
  2. 資源限制

    • 限制并發異步任務數量
    • 對重要任務設置優先級
  3. 監控告警

    • 監控線程池關鍵指標
    • 設置異常告警閾值

七、與其他技術的整合

7.1 與Spring Retry整合

實現異步任務失敗重試:

@Async
@Retryable(value = {RemoteAccessException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000, multiplier = 2))
public CompletableFuture<String> callExternalService() {// 調用可能失敗的外部服務return CompletableFuture.completedFuture(externalService.call());
}// 重試全部失敗后的處理
@Recover
public CompletableFuture<String> recover(RemoteAccessException e) {return CompletableFuture.completedFuture("默認返回值");
}

7.2 與Spring Cache整合

異步緩存更新:

@Async
@CacheEvict(value = "users", key = "#userId")
public void evictUserCacheAsync(String userId) {// 異步清理緩存
}@Async
@CachePut(value = "users", key = "#user.id")
public CompletableFuture<User> updateUserAsync(User user) {// 異步更新用戶并更新緩存return CompletableFuture.completedFuture(userRepository.save(user));
}

7.3 與WebFlux響應式編程對比

特性@AsyncWebFlux
編程模型命令式響應式
線程模型線程池-based事件循環
資源消耗較高(每個請求一個線程)較低(少量線程處理所有請求)
學習曲線較低較高
適用場景傳統Servlet應用高并發IO密集型應用
背壓支持不支持支持
集成復雜度簡單中等

八、常見問題與解決方案

8.1 問題排查表

問題現象可能原因解決方案
@Async方法不異步執行同類調用確保通過Spring代理調用,使用@Autowired注入自身
未加@EnableAsync在主配置類添加@EnableAsync
異步方法拋出異常不顯示未正確處理AsyncUncaughtException實現AsyncUncaughtExceptionHandler
線程池不生效未正確命名或注入確保@Async(“executorName”)與@Bean名稱一致
應用關閉時任務丟失未配置優雅關閉設置setWaitForTasksToCompleteOnShutdown(true)和awaitTerminationSeconds
性能未提升反而下降線程池配置不合理調整核心/最大線程數和隊列容量
ThreadLocal值丟失線程切換導致上下文丟失使用TaskDecorator傳遞上下文

8.2 實戰問題案例

案例1:數據庫連接泄漏

@Async
public void processData() {// 錯誤示范:未關閉ConnectionConnection conn = dataSource.getConnection();// 使用conn...
}

解決方案

@Async
public void processData() {try (Connection conn = dataSource.getConnection()) {// 使用conn...} catch (SQLException e) {// 異常處理}
}

案例2:訂單超時未支付取消

@Async
@Scheduled(fixedDelay = 60000)  // 每分鐘檢查一次
public void cancelUnpaidOrders() {List<Order> unpaidOrders = orderRepository.findByStatusAndCreateTimeBefore(OrderStatus.UNPAID, LocalDateTime.now().minusMinutes(30));unpaidOrders.forEach(order -> {order.setStatus(OrderStatus.CANCELLED);orderRepository.save(order);notificationService.sendCancelNotice(order);});
}

九、總結

9.1 核心要點總結

  1. 基礎使用

    • @EnableAsync啟用支持
    • @Async標注異步方法
    • 避免同類調用
  2. 線程池配置

    • 生產環境必須自定義線程池
    • 合理設置核心參數
    • 監控線程池狀態
  3. 異常處理

    • 區分返回值類型選擇處理方式
    • 實現全局異常處理器
    • 日志記錄完整上下文
  4. 高級特性

    • 組合多個異步操作
    • 事務邊界處理
    • 條件異步執行
  5. 最佳實踐

    • 命名規范
    • 防御性編程
    • 資源清理
    • 上下文傳遞

9.2 完整示例代碼

訂單處理服務示例

@Service
public class OrderProcessingService {private static final Logger logger = LoggerFactory.getLogger(OrderProcessingService.class);@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate PaymentService paymentService;@Autowiredprivate NotificationService notificationService;@Async("orderTaskExecutor")@Transactional(propagation = Propagation.REQUIRES_NEW)public CompletableFuture<OrderResult> processOrderAsync(Order order) {logger.info("開始異步處理訂單: {}", order.getId());long startTime = System.currentTimeMillis();try {// 1. 保存訂單Order savedOrder = orderRepository.save(order);// 2. 處理支付PaymentResult paymentResult = paymentService.processPayment(savedOrder);if (!paymentResult.isSuccess()) {throw new PaymentException("支付處理失敗: " + paymentResult.getErrorMessage());}// 3. 更新訂單狀態savedOrder.setStatus(OrderStatus.PAID);orderRepository.save(savedOrder);// 4. 發送通知notificationService.sendOrderConfirmation(savedOrder);long elapsed = System.currentTimeMillis() - startTime;logger.info("訂單處理完成: {}, 耗時: {}ms", savedOrder.getId(), elapsed);return CompletableFuture.completedFuture(new OrderResult(true, "訂單處理成功", savedOrder));} catch (PaymentException e) {logger.error("訂單支付異常: {}", order.getId(), e);return CompletableFuture.completedFuture(new OrderResult(false, e.getMessage(), order));} catch (Exception e) {logger.error("訂單處理未知異常: {}", order.getId(), e);return CompletableFuture.failedFuture(e);}}// 批量異步處理訂單@Async("batchOrderExecutor")public CompletableFuture<Void> processOrdersBatch(List<Order> orders) {List<CompletableFuture<OrderResult>> futures = orders.stream().map(this::processOrderAsync).collect(Collectors.toList());return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).exceptionally(ex -> {logger.error("批量處理訂單異常", ex);return null;});}
}// 配置類
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(20);executor.setQueueCapacity(100);executor.setThreadNamePrefix("Order-Async-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.setWaitForTasksToCompleteOnShutdown(true);executor.setAwaitTerminationSeconds(60);executor.initialize();return executor;}@Bean(name = "batchOrderExecutor")public Executor batchOrderExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(50);executor.setThreadNamePrefix("Batch-Order-");executor.initialize();return executor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new OrderAsyncExceptionHandler();}
}// 全局異常處理器
public class OrderAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(OrderAsyncExceptionHandler.class);@Overridepublic void handleUncaughtException(Throwable ex, Method method, Object... params) {logger.error("異步訂單處理異常 - 方法: {}, 參數: {}", method.getName(), Arrays.toString(params), ex);// 發送告警郵件if (ex instanceof CriticalOrderException) {sendCriticalAlert(method, ex, params);}}private void sendCriticalAlert(Method method, Throwable ex, Object... params) {// 實現告警邏輯}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79408.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79408.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79408.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單的強化學習舉例

1&#xff0c;定義獎勵函數 首先&#xff0c;需要根據具體的任務需求來定義獎勵函數。例如&#xff0c;對于機器人導航任務&#xff0c;可以根據機器人與目標點的距離來定義獎勵函數&#xff1a; import numpy as npdef navigation_reward(robot_position, target_position):…

css背景相關

背景書寫 background: url(src); // 注意&#xff1a;在寫動態樣式時&#xff0c;backgournd賦值格式錯誤&#xff0c;是不會在瀏覽器dom的style上顯示的 // 但是可以創建不可見的img&#xff0c;預加載來提高性能背景也會加載圖片資源 同img的src一樣&#xff0c;background也…

opencascade.js stp vite 調試筆記

Hello, World! | Op enCascade.js cnpm install opencascade.js cnpm install vite-plugin-wasm --save-dev 當你不知道文件寫哪的時候trae還是有點用的 ‘’‘ import { defineConfig } from vite; import wasm from vite-plugin-wasm; import rollupWasm from rollup/plug…

線程的一些事(2)

在java中&#xff0c;線程的終止&#xff0c;是一種“軟性”操作&#xff0c;必須要對應的線程配合&#xff0c;才能把終止落實下去 然而&#xff0c;系統原生的api其實還提供了&#xff0c;強制終止線程的操作&#xff0c;無論線程執行到哪&#xff0c;都能強行把這個線程干掉…

BGP實驗練習1

需求&#xff1a; 要求五臺路由器的環回地址均可以相互訪問 需求分析&#xff1a; 1.圖中存在五個路由器 AR1、AR2、AR3、AR4、AR5&#xff0c;分屬不同自治系統&#xff08;AS&#xff09;&#xff0c;AR1 在 AS 100&#xff0c;AR2 - AR4 在 AS 200&#xff0c;AR5 在 AS …

滑動窗口——將x減到0的最小操作數

題目&#xff1a; 這個題如果我們直接去思考方法是很困難的&#xff0c;因為我們不知道下一步是在數組的左還是右操作才能使其最小。正難則反&#xff0c;思考一下&#xff0c;無論是怎么樣的&#xff0c;最終這個數組都會分成三個部分左中右&#xff0c;而左右的組合就是我們…

C++ RAII機制

RAII&#xff08;Resource Acquisition Is Initialization&#xff09;是一種編程范式&#xff0c;核心思想是&#xff1a;資源的生命周期與對象綁定——對象創建時獲取資源&#xff0c;對象銷毀時自動釋放資源。這種機制通過構造函數和析構函數的配對執行&#xff0c;確保資源…

連續抵消解碼器--Successive Cancellation decoder(SC 解碼器)

在這里&#xff0c;我們來看一下&#xff08;Arikan&#xff0c;2009&#xff09;中提供的連續取消解碼算法。 顧名思義&#xff0c;SC解碼算法從u0開始按順序解碼比特。 凍結的比特節點總是被解碼為0。 在解碼ui時&#xff0c;根據以下規則使用由向量表示的可用比特來解碼u…

suricata之規則去重

一、環境和背景 1.1 環境 OS: Ubuntu 22.04.5 LTS IDE: vscode suricata: suricata 7.0.5 1.2 背景 在添加規則時&#xff0c;為了給規則分類&#xff0c;將不同類別的規則寫入不同的文件。 在規則加載時兩條不同的規則卻被認為是重復的&#xff0c;因此記錄一下去重邏輯。…

vue vite 無法熱更新問題

一、在vue頁面引入組件CustomEmployeesDialog&#xff0c;修改組件CustomEmployeesDialog無法熱更新 引入方式&#xff1a; import CustomEmployeesDialog from ../dialog/customEmployeesDialog.vue 目錄結構&#xff1a; 最后發現是引入import時&#xff0c;路徑大小寫與目…

深入理解 Linux 權限控制機制

引言 在 Linux 系統中&#xff0c;權限控制是保障系統安全的核心機制。通過限制用戶對文件和資源的訪問&#xff0c;它能有效防止未授權操作&#xff0c;保護數據不被篡改或泄露。合理設置權限不僅有助于實現用戶隔離和最小權限原則&#xff0c;還能降低系統被濫用或攻擊的風險…

Oracle版本、補丁及升級(12)——版本體系

12.1. 版本體系 Oracle作為最流行的一款關系數據庫軟件產品,其擁有自己一套成熟的版本管理體系。具體版本體系以12c為分界線,前后版本體系分別不同。 ???????12.1.1. 12c之前版本 12c之前的Oracle,版本共有5位阿拉伯數字組成,其中的每位數字,都有各自的含義,具…

Maven 中的 pom.xml 文件

目錄標題 1、根標簽 <project> 的直接子標簽順序?2、常見子標簽內部順序?2.1、<build> 標簽內部順序2.2、<dependencies> 標簽內部順序 3、modelVersion 為什么是 4.0.0 &#xff1f;4、<parent> 標簽&#xff1f;??4.1、為什么需要 <parent>…

方案精讀:華為與中軟-智慧園區解決方案技術主打膠片【附全文閱讀】

該文檔是華為與中軟國際的智慧園區輕量化解決方案推介&#xff0c;主要面向園區管理者、運營者及相關企業決策人。其核心圍繞園區痛點&#xff0c;闡述智慧園區的發展趨勢。 方案涵蓋綜合安防、便捷通行、設備管理等多領域應用場景&#xff0c;通過智能視頻監控、人臉識別、遠程…

# KVstorageBaseRaft-cpp 項目 RPC 模塊源碼學習

KVstorageBaseRaft-cpp 項目 RPC 模塊源碼學習 。 一、項目簡介 KVstorageBaseRaft-cpp 是一個基于 Raft 一致性算法實現的分布式 KV 存儲系統&#xff0c;采用 C 開發。項目的核心目標是幫助開發者理解 Raft 原理和分布式 KV 存儲的基本實現。RPC 模塊是分布式系統通信的關…

TeledyneLeCroy在OFC2025 EA展臺上展示了其400G/800G的全包圍的測試解決方案,滿足了UEC聯盟和UALINK聯盟的技術需求

Teledyne LeCroy在OFC 2025上的EA展臺 在2025年3月26日至28日于美國圣地亞哥舉辦的OFC&#xff08;Optical Fiber Communication Conference and Exhibition&#xff09;展會上&#xff0c;全球領先的測試測量解決方案提供商Teledyne LeCroy隆重展示了其最新研發的800G網絡測試…

新一代電動門“攻克”行業痛點,遠峰科技打造“智能出入”新標桿

在2025上海國際車展期間&#xff0c;遠峰科技舉辦了一場面向車企合作伙伴和媒體的智能汽車解決方案實車展示會。 在這其中&#xff0c;遠峰科技的新一代電動門首次亮相&#xff0c;突破性的解決了行業普遍存在的“運行抖動不平順”、“窄車位車門開度過小”、“障礙物識別不準…

WEB UI自動化測試之Pytest框架學習

文章目錄 前言Pytest簡介Pytest安裝Pytest的常用插件Pytest的命名約束Pytest的運行方式Pytest運行方式與unittest對比主函數運行命令行運行執行結果代碼說明 pytest.ini配置文件方式運行&#xff08;推薦&#xff09;使用markers標記測試用例 pytest中添加Fixture&#xff08;測…

機器學習簡單概述

Chatgpt回答&#xff1a; 機器學習&#xff1a;機器學習是人工智能的一個分支&#xff0c;側重于通過數據訓練模型&#xff0c;使計算機能夠根據數據進行預測、分類、回歸等任務。它通過算法從歷史數據中學習規律&#xff0c;然后在新數據上進行推斷。機器學習包括多種算法&…

openjdk底層匯編指令調用(一)——匯編指令及指令編碼基礎

匯編指令 計算機在執行過程時只識別代表0或者1的電信號。因此為了讓計算機能夠執行則須向計算機輸入一系列01構成的指令。 例如在x64平臺下&#xff0c;0x53&#xff0c;二進制為01010011&#xff0c;表示將rbx寄存器中的值壓棧。 但是&#xff0c;對于程序員而言&#xff0c;…