2012-05-15 12 views
12

Tôi không chắc liệu từ khóa dễ bay hơi cũng có nên được sử dụng cho các nguyên thủy không. Tôi có một thành viên của lớp được thiết lập/gán bởi một luồng và được truy cập bởi một luồng khác. Tôi có nên tuyên bố thành viên này dễ bay hơi không?java - từ khóa dễ bay hơi cũng không phải là nguyên thủy

private /* volatile */ Object o; 

public void setMember(Object o) { 
    this.o = o; 
} 

public Object getMember() { 
    return o; 
} 

Ở đây, setMember (...) được gọi bằng một chuỗi và getMember() được gọi bởi một chuỗi khác.

Nếu đó là một boolean, ví dụ, câu trả lời sẽ là có.

Tôi đang sử dụng Java 1.4 và thành viên trong trường hợp này là chỉ đọc. Vì vậy, tôi chỉ quan tâm đến khả năng hiển thị trong trường hợp này, do đó câu hỏi của tôi về từ khóa dễ bay hơi.

Trả lời

11

Có - volatile có cùng ý nghĩa chính xác với các trường loại tham chiếu mà nó có cho các trường kiểu nguyên thủy. Ngoại trừ trường hợp loại tham chiếu, các thành viên của đối tượng mà trường đó đề cập đến phải cũng được thiết kế để truy cập đa luồng.

+0

Chỉ tò mò về tuyên bố này - các thành viên của đối tượng mà trường đề cập cũng phải được thiết kế để truy cập đa luồng - sẽ tuyệt vời nếu bạn có thể mở rộng về lý do tại sao nó như vậy? – jtkSource

+0

@jtkSource: dễ bay hơi chỉ ảnh hưởng đến trường, nhưng trường chỉ chứa tham chiếu. Vì vậy, dễ bay hơi đảm bảo rằng các luồng khác nhìn thấy các cập nhật cho tham chiếu đó, nhưng nếu đối tượng được gọi đến không sử dụng biến động hoặc đồng bộ đúng cách, thì các luồng khác có thể không nhìn thấy các cập nhật của các trường của đối tượng đó. –

+0

chỉ cần suy nghĩ ra - vì vậy nếu một biến dễ bay hơi đề cập đến một đối tượng, không phải các biến không dễ bay hơi cũng được thực hiện 'visibile' một cách nhất quán trong bối cảnh của đối tượng tuyên bố nó dễ bay hơi? Nếu có các đối tượng khác cũng tham chiếu đến 'đối tượng được gọi' này theo cách không dễ bay hơi, thì chỉ những đối tượng đó có nguy cơ không nhìn thấy biến trong trạng thái nhất quán không? sẽ có một cơ hội mà có hai biểu diễn của cùng một đối tượng trong bộ nhớ? - Hãy cho tôi biết nếu tôi đã nhầm lẫn logic của tôi. – jtkSource

6

Bạn có thể và điều này có thể hữu ích, nhưng hãy nhớ rằng từ khóa chỉ áp dụng cho cài đặt của tham chiếu. Nó không ảnh hưởng đến khả năng hiển thị đa luồng của các thuộc tính bên trong đối tượng đó. Nếu nó là stateful, bạn có thể muốn đồng bộ hóa xung quanh mỗi truy cập vào nó anyway, để đảm bảo mong muốn xảy ra-trước khi các mối quan hệ.

4

Có, mã của bạn là chính xác. Trong trường hợp này tham chiếu chính nó là dễ bay hơi, vì vậy cơ hội để tham chiếu được tự động nhìn thấy trong tất cả các chủ đề khác, nhưng không thay đổi đối tượng đang được tham chiếu.

0

Nếu chúng ta nhìn lên AtomicInteger lớp, nó đã tuyên bố value như volatile, Vì vậy, nó có thể được sử dụng trong môi trường đa luồng mà không cần bất kỳ vấn đề chủ đề bộ nhớ cache.

public class AtomicInteger { 
    private volatile int value; 

    /** 
    * Gets the current value. 
    * 
    * @return the current value 
    */ 
    public final int get() { 
     return value; 
    } 

    /** 
    * Sets to the given value. 
    * 
    * @param newValue the new value 
    */ 
    public final void set(int newValue) { 
     value = newValue; 
    } 

} 

Nhưng nếu bạn nghĩ tham chiếu đến AtomicInteger, giá sách sẽ được sửa đổi với các đối tượng AtomicInteger khác nhau theo nhiều chủ đề; sau đó bạn cần dễ bay hơi cho tham chiếu đó.

private volatile AtomicInteger reference = new AtomicInteger(0); 

Chủ yếu là không phải vậy; chỉ giá trị của đối tượng sẽ thay đổi; do đó tuyên bố nó là cuối cùng.

private final AtomicInteger reference = new AtomicInteger(0);