深度解析Spring非同步註解

一、Spring非同步註解阻塞

Spring非同步註解是提高程序效率的重要手段之一,但是如果不合理使用,也會帶來阻塞問題。比如,如果在使用Spring非同步註解時,註解了過多的方法或者使用了分段鎖,就會導致性能反而下降。

@Async
public Future<Void> computeAsync() {
    return CompletableFuture.completedFuture(null);
}

為了避免Spring非同步註解阻塞,可以採取以下措施:

1.合理控制非同步請求的個數,以充分利用資源提高效率;

2.使用分散式鎖代替分段鎖;

3.使用非同步隊列等輔助類提高處理效率。

二、Spring非同步註解有什麼弊端

Spring非同步註解雖然可以提高程序效率,但也存在一些弊端:

1.非同步調用可能導致程序執行順序與代碼編寫順序不一致,導致程序邏輯異常;

2.當非同步執行的任務執行時間過長,可能導致線程池的擁堵等問題;

3.因為非同步調用是在新的線程中執行,所以在非同步調用過程中,線程上下文不能被當做請求上下文傳遞。

三、Spring非同步註解怎麼實現

Spring非同步註解的實現主要依賴於兩個核心類:

1. AsyncAnnotationBeanPostProcessor:用於處理Bean中標註@Async註解的方法,生成非同步執行代理;

2. AsyncExecutionInterceptor:用於創建執行非同步任務的Runnable實例。

具體實現方法如下:

@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
 
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(2000);
        executor.setThreadNamePrefix("async-thread-");
        executor.initialize();
        return executor;
    }
}

@Service
public class AsyncService {
 
    @Async
    public Future<String> doSomeLongOperation() {
        //long operation
        return CompletableFuture.completedFuture(result);
    }
}

public class AsyncAction {
    private AsyncService asyncService;
    //調用非同步方法並獲得結果
    public void doAction() {
        Future<String> result = asyncService.doSomeLongOperation();
        //...
    }
}

四、Spring非同步註解原理

Spring非同步註解的原理是通過AOP技術,對被@Async註解標記的方法,進行攔截並創建非同步代理,然後將非同步調用轉發到線程池執行,最後返回Future對象以便其它方法繼續執行。

五、Spring非同步註解不生效

Spring非同步註解不生效的原因主要有以下幾點:

1.項目沒有開啟非同步執行支持,需要@EnableAsync註解

2.方法沒有被public修飾;

3.在同一個類中調用非同步方法,沒有使用self調用,導致代理失效。

六、Spring開啟非同步註解

Spring開啟非同步註解需要通過@EnableAsync註解來開啟,並且需要通過@Configuration類中覆蓋AsyncConfigurerSupport類的getAsyncExecutor方法來配置線程池(可選)。

@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
 
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(2000);
        executor.setThreadNamePrefix("async-thread-");
        executor.initialize();
        return executor;
    }
}

七、Spring非同步註解是什麼

Spring非同步註解是標記一個方法會被非同步調用的註解。在方法上加上@Async註解,使其可以被多線程執行,從而提高程序的效率。

八、Spring非同步註解使用場景

Spring非同步註解非常適合處理長時間耗時的任務,例如大文件讀取、大數據處理、網路IO等。

九、Spring非同步註解事務不起作用

Spring事務管理默認是基於線程的,即同一個線程中的各個事務共享同一個連接和事務,但是如果在非同步調用中開啟了新的線程,那麼事務就無法在新線程中被識別,因此在使用Spring非同步註解時,需要注意事務的傳播屬性,可以在註解中指定PROPAGATION_REQUIRES_NEW級別的傳播行為來實現非同步調用時的事務管理。

@Service
public class AsyncService {
 
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Async
    public Future<String> doSomeLongOperation() {
        //long operation
        return CompletableFuture.completedFuture(result);
    }
}

附:SpringBoot非同步註解示例

對於SpringBoot項目,使用非同步註解的方法與普通Spring項目一致,只需要在SpringBoot的啟動類中使用@EnableAsync註解,然後在需要非同步執行的方法上使用@Async註解即可。

@SpringBootApplication
@EnableAsync
public class Application {
    //...
}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/246905.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 13:18
下一篇 2024-12-12 13:18

相關推薦

發表回復

登錄後才能評論