2011-08-16 30 views
18

Chúng tôi thường sử dụng volatile để đảm bảo rằng biến điều kiện có thể hiển thị cho mọi Chủ đề.Tôi có cần biến động cho các biến của các kiểu tham chiếu không?

Tôi thấy các trường volatile là tất cả primitive type trong mã cho đến thời điểm này.

Trường object có vấn đề này không? Ví dụ:

class a { 

    public String str; 

    public List list; 

} 

Nếu có một số chủ đề sẽ truy cập vào str và danh sách, tôi phải thêm 'dễ bay hơi'?

Tôi đoán mỗi quyền truy cập vào Object sẽ nhận trực tiếp từ HeapObject sẽ không được lưu vào bộ nhớ cache như loại nguyên thủy.

Đúng không?

Trả lời

2

Bạn thêm volatile keyword để thông báo cho trình biên dịch biết ràng buộc của nó là change. để tất cả chủ đề

tái xác nhận rằng local cached copy của họ là giống như của một bản gốc, nếu có sự thay đổi nó

cập nhật nó. và bạn thường thấy nó với Primitive vì thường các giá trị nguyên thủy được tăng lên

hoặc giảm dần vv theo các luồng khác nhau. nhưng đối tượng, đặc biệt là Danh sách sẽ không bao giờ thay đổi vì chỉ

một tham chiếu đến đối tượng của nó. nếu bạn đang gán đối tượng khác nhau để biến tương tự, tại thời gian chạy

sau đó bạn có thể

làm ..

+0

Bạn có nghĩa là tham chiếu có thể được lưu vào bộ nhớ cache như nguyên thủy? – Hesey

+0

@Hersey Vâng, đó là chính xác. Xem pvblivs trả lời quá. – Bringer128

+1

Những gì tôi có một trường (Object o = null;) nhưng nó không thể được thiết lập cuối cùng vì nó được khởi tạo bên ngoài constructor, tuy nhiên - nó không bao giờ bị thay đổi thành bất kỳ giá trị nào khác sau khi khởi tạo - và nó không được đọc trong khi nó null (thậm chí không kiểm tra null) ... nó chỉ được đọc sau khi nó đã được khởi tạo. Trong trường hợp này, không cần phải làm gì đặc biệt - đúng không? (nhiều chủ đề có thể truy cập đối tượng) – ycomp

24

Bạn cần phải phân biệt giữa các tham chiếu đối tượng và đối tượng thực tế.

  • Để tham chiếu công cụ sửa đổi trường của bạn có liên quan. Khi bạn thay đổi tham chiếu đến đối tượng khác (ví dụ: tham chiếu một Chuỗi khác), thay đổi có thể không được nhận thấy bởi một Chủ đề khác. Nếu bạn muốn thực thi khả năng hiển thị, bạn phải sử dụng final hoặc volatile.

  • đối tượng thực tế trên heap không bị ảnh hưởng bởi công cụ sửa đổi trường. Thay vào cách bạn nhìn thấy từng lĩnh vực của đối tượng này được xác định bởi modifier lĩnh vực riêng của mình theo các quy tắc tương tự (là nó volatile hay final? Nếu không, tầm nhìn cho Chủ đề đồng thời là không được thực thi)

Vì vậy, câu trả lời là : Có, bạn phải thêm volatile hoặc final. Về mặt phong cách, nó sẽ tốt hơn nhiều để làm cho lĩnh vực cuối cùng, mặc dù. Nó có cùng hiệu quả Thread-wise nhưng cũng là một câu lệnh mạnh hơn: Trường này không thể thay đổi được - đó là lý do tại sao nó có thể được lưu trữ một cách không cần thiết bởi JVM. Và vì lý do tương tự, nó đi kèm với một lợi ích hiệu suất nhỏ so với volatile, Java không cần quan tâm liệu trường đó có thay đổi một lần nữa và không cần phải thêm phí.

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