2012-03-21 33 views
5

Lớp này có an toàn không?AtomicInteger vs getters/setters đồng bộ

Có thể thấy giá trị không phù hợp không? Cho phép nói giá trị ban đầu của một là 80. Chủ đề 1 gọi setA(100) và đi vào chức năng nhưng chưa gọi a.set(100) và Chủ đề 2 đồng thời gọi getA(). Có thể cho Chủ đề 2 thấy 80 không?

public class A { 
    private AtomicInteger a; 

    public int getA() { 
     return a.get() 
    } 

    public void setA(int newVal){ 
     a.set(newVal); 
    } 
} 

Tôi biết rằng việc đồng bộ hóa sẽ đảm bảo chuỗi 2 thấy 100, nhưng không chắc chắn với AtomicInteger.

Trả lời

9

Lớp học này có an toàn không?

Vâng.

Cuộc gọi 1 cuộc gọi được đặt (100) và nhập hàm nhưng chưa gọi a.set (100) và Chủ đề 2 đồng thời gọi getA(). Có thể cho Chủ đề 2 thấy 80 không?

Có. Cho đến khi mã rào cản bộ nhớ đồng bộ hóa trường biến động bên trong của AtomicInteger hoàn thành, điều kiện chủng tộc có thể hiển thị 80 hoặc 100.

Chủ đề 1 thậm chí có thể nhập phương thức AtomicInteger.set và trước khi chuyển trường bên trong và vẫn có thể trả về 80 bằng phương pháp AtomicInteger.get.

Không có đảm bảo nào về khi giá trị sẽ được cập nhật trong các chủ đề khác. Điều được đảm bảo là khi hoàn tất get(), bạn nhận được giá trị được đồng bộ hóa gần đây nhất và khi hoàn tất set(), tất cả các chuỗi khác sẽ thấy các cập nhật.

Không đảm bảo về thời gian thời gian của các cuộc gọi getter và setter trong các chủ đề khác nhau.

1

Như @Gray lưu ý, có khả năng xảy ra tình trạng chủng tộc ở đây.

Gọi get và sau đó set không phải là hoạt động nguyên tử. The Atomic* classes cung cấp hoạt động cập nhật điều kiện nguyên tử không khóa, compareAndSet - bạn nên sử dụng thao tác đó để đảm bảo an toàn cho luồng.

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