Tôi đọc lớp FutureTask trong jsr166, thấy rằng đối tượng kết quả là không bay hơi, các chú thích trong mã là "không bay hơi, được bảo vệ bởi nhà nước đọc/ghi" dòng 75, trạng thái là biến động int. Tôi đã đọc Mô hình bộ nhớ Java từ Java Language Spec, nhưng không tìm thấy câu trả lời chính xác. Có ai biết lý do không?tại sao đối tượng kết quả trong FutureTask là không dễ bay hơi?
8
A
Trả lời
5
xem xét chương trình này:
volatile int state;
Integer result;
void succeed(Integer result)
if(state==PENDING) vr0
this.result = result; w1
state = DONE; vw1
Integer peekResult()
if(state==DONE) vr2
return result; r2
return null;
Nếu không ổn định đọc vr2
thấy DONE
, nó có nghĩa là nó sẽ xảy ra sau khi biến động ghi vw1
. Vì vậy, chúng tôi đã xảy ra trước khi các mối quan hệ: w1 -> vw1 -> vr2 -> r2
. Do đó, viết w1
hiển thị để đọc r2
.
Tuy nhiên succeed()
không phải là chủ đề an toàn, vì vr0
và vw1
không phải là nguyên tử. Nếu chúng tôi sử dụng CAS
void succeed(Integer result)
if(compareAndSet(state, PENDING, DONE)) vr0+vw0
this.result = result; w1
nó sẽ khắc phục vấn đề nguyên tử. Tuy nhiên, hiện tại, w1
không nhất thiết hiển thị đối với r2
. Các hiệu ứng nhớ rào cản của CAS là loại giống như
void succeed(Integer result)
if(state==PENDING) vr0
state=DONE; vw0
this.result = result; w1
Chúng tôi có ở đây vw0 -> vr2 -> r2
, nhưng w1
không nằm trong chuỗi, không có w1 -> r2
Chúng ta phải làm những ghi biến động state=DONE
sau w1
thành lập xảy ra trước chuỗi.
void succeed(Integer result)
if(state==PENDING) vr0
state=TMP; vw0
this.result = result; w1
state=DONE; vw1
hoặc trong CAS
void succeed(Integer result)
if(compareAndSet(state, PENDING, TMP)) vr0+vw0
this.result = result; w1
state=DONE; vw1
Các vấn đề liên quan
- 1. lý do tại sao không thể là một đối tượng dễ bay hơi gọi hàm thành viên không linh hoạt
- 2. Khai báo một đối tượng dễ bay hơi
- 3. Xác định đối tượng lớp dễ bay hơi
- 4. Không thể gán một đối tượng cho một đối tượng dễ bay hơi
- 5. ngữ nghĩa dễ bay hơi trong C99
- 6. dễ bay hơi DateTime
- 7. dễ bay hơi weirdness
- 8. Biến dễ bay hơi
- 9. Tại sao con trỏ trỏ tới điểm dễ bay hơi, như "int dễ bay hơi * p", hữu ích?
- 10. Go có hỗ trợ các biến dễ bay hơi/không dễ bay hơi không?
- 11. quá tải dễ bay hơi?
- 12. Android dễ bay hơi không hoạt động?
- 13. dễ bay hơi và Thread.MemoryBarrier trong C#
- 14. dễ bay hơi tương đương trong VB.NET
- 15. Trong khi (! Dễ bay hơi); làm gì?
- 16. Là một int dễ bay hơi trong Java thread-safe?
- 17. Tại sao các biến trong Java dễ bay hơi theo mặc định?
- 18. tại sao không thể biến cục bộ dễ bay hơi trong C#?
- 19. Dễ bay hơi HashMap vs ConcurrentHashMap
- 20. Java câu hỏi biến dễ bay hơi
- 21. Concurrency in Practice - dễ bay hơi ++
- 22. Tại sao loại bỏ vòng loại dễ bay hơi trong một hàm gọi cảnh báo?
- 23. nhầm lẫn dễ bay hơi và đôi
- 24. Ngữ nghĩa cấu trúc dễ bay hơi
- 25. Sử dụng đúng sig_atomic_t dễ bay hơi
- 26. mất vòng loại dễ bay hơi const
- 27. là biến dễ bay hơi được đồng bộ hóa? (java)
- 28. dễ bay hơi và có thể thay đổi trong C++
- 29. Quá tải trên const và dễ bay hơi - tại sao nó hoạt động theo tham chiếu?
- 30. Tại sao địa chỉ của biến dễ bay hơi này luôn ở mức 1?
câu trả lời rất hữu ích, hiểu thêm rõ ràng – taigetco