2013-01-21 30 views
8

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?

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ì vr0vw1 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 
+0

câu trả lời rất hữu ích, hiểu thêm rõ ràng – taigetco

Các vấn đề liên quan