為了總結這個問題,我試圖在同步方法中呼叫一些用 @async 注釋的方法。使用@async 的原因是因為我希望回傳 post 方法的回應(以減少客戶端的等待時間)并繼續做一些后期處理作業(重置某些屬性)。但是,由于 POST 方法涉及更改圖形資料庫,因此我使用 synchronized 關鍵字宣告該方法,以防止在進行另一次計算時更改圖形資料庫。這樣做的結果似乎是兩個執行緒正在進入同步方法,這不應該發生嗎?
@RestController
public class Controller {
@PostMapping(path = “/compute”)
public synchronized String compute() {
System.out.println(“===== > In thread: “ Thread.currentThread().getName());
System.out.print(“===== > Doing some work in compute”);
ResetService.reset()
Return(“===== > done computing”)
}
@Service
public class ResetService {@Async public void reset (){
System.out.println(“===== > resetting in thread: “ Thread.currentThread().getName());
#(resetting some properties in neo4j graph database)
resetMethod();
System.out.print(“===== > Done Resetting”);
}
這會給我一個類似于這樣的輸出:
===== > 在執行緒中:http-nio-10080-exec-2
===== > 在計算方面做一些作業
===== > 完成計算
=====> 在執行緒中重置:Async-1
===== > In Thread: http-nio-10080-exec-3
===== > Doing some work in compute
===== > Done Resetting
My understanding of Synchronized method is that it only allows a single thread to enter the method at any time. But it seems like there are two threads running the Synchronized compute method at the same time. I tried to come up with some reasons for this and the two main ones I could think of are:
Due to different instances of the Controller class, however I recalled reading somewhere that a RESTController is a singleton scope by default, so it shouldn’t be due to this?
Context switching? Does synchronized method allow for context switching from one thread to another?
如果我的問題的任何部分令人困惑,我深表歉意,因為我對 Java Spring/Spring Boot 尤其是并發、多執行緒等概念相對較新。如果您需要我澄清我的問題的任何部分,請告訴我。
uj5u.com熱心網友回復:
當您在reset()同步方法中呼叫異步方法時compute(),后一種方法不會等待reset()完成。相反,它將產生一個新執行緒來處理代碼執行,reset()然后立即進入下一行Return(“===== > done computing”)。之后,該方法將完成。當它完成時,將允許呼叫一個新執行緒compute(),即使reset()之前進入的執行緒的呼叫compute()仍在單獨的執行緒中運行。
所以要更清楚一點,該方法compute()不是由兩個執行緒同時進入的。它看起來只是這樣,因為從 thread 列印的部分文本http-nio-10080-exec-3出現在 thread 的Done Resetting列印之前Async-1。因此,您的代碼按預期作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/423034.html
標籤:
