我有一個簡單的 Spring 控制器,它有一個 Spring 服務作為依賴項。在服務類中,我有一個名為 flag 的 int 型別的靜態 volatile 欄位。當我通過控制器呼叫 createFlux() 方法時,標志設定為 5,然后創建一個新的 Flux,它每秒檢查標志,并根據標志值列印一條訊息。由于 delayElements 方法語意,代碼將并行執行。之后,如果我呼叫 changeFlag() 方法,該方法會更改標志的值,并且由于標志變數是易失的,我希望列印的訊息會發生變化,但這不會發生。
這是代碼:
@RestController
public class MyController {
@Autowired private MyService myService;
@GetMapping("createFlux")
public void createFlux() {
myService.createFlux();
}
@GetMapping("changeFlag")
public void changeFlag() {
myService.changeFlag();
}
}
@Service
public class MyService {
private static volatile int flag = 3;
public void changeFlag() {
flag = 3;
System.out.println("############# Flag = " flag);
}
public void createFlux() {
flag = 5;
System.out.println("Flag = " flag);
Flux.generate(sink -> {
if (flag == 3) {
sink.next("Stop");
} else {
sink.next("Start");
}
}).delayElements(Duration.ofSeconds(1)).subscribe(s -> System.out.println(Thread.currentThread().getName() " : " s));
}
}
這是控制臺中的輸出:
Flag = 5
parallel-1 : Start
parallel-2 : Start
parallel-3 : Start
parallel-4 : Start
############# Flag = 3
parallel-5 : Start
parallel-6 : Start
parallel-7 : Start
parallel-8 : Start
parallel-1 : Start
parallel-2 : Start
parallel-3 : Start
parallel-4 : Start
parallel-5 : Start
parallel-6 : Start
parallel-7 : Start
parallel-8 : Start
parallel-1 : Start
parallel-2 : Start
parallel-3 : Start
parallel-4 : Start
parallel-5 : Start
parallel-6 : Start
parallel-7 : Start
parallel-8 : Start
parallel-1 : Start
parallel-2 : Start
parallel-3 : Start
parallel-4 : Start
parallel-5 : Start
parallel-6 : Start
parallel-7 : Start
parallel-8 : Start
parallel-1 : Stop
parallel-2 : Stop
parallel-3 : Stop
parallel-4 : Stop
parallel-5 : Stop
parallel-6 : Stop
從輸出可以看出,即使 flag 的值更改為 3,它也會繼續列印訊息 Start。一段時間后,列印的訊息也發生了變化。我想有一些快取或類似的東西,但是 volatile 變數沒有被快取。
問題是 - 這是一個錯誤還是我錯過了什么?
uj5u.com熱心網友回復:
為一堆元素立即執行生成消費者。您可以通過在以下內容之后添加日志來輕松確認generate:
Flux.generate(...).doOnNext(e -> log.info("executed: {}", e))
印刷:
2022-01-20 13:31:50,346 INFO parallel-1 - Flag = 5
2022-01-20 13:31:50,349 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,351 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,352 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,352 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,352 INFO parallel-1 - executed: Start
2022-01-20 13:31:50,352 INFO parallel-1 - executed: Start
generate方法根據下游的需求發出元素。它首先生成 32 個元素并緩沖它們。當下游開始處理元素并且緩沖區大小低于閾值時,它會發出更多元素。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/417312.html
標籤:
