2012-05-15 14 views
12

Nie jestem pewien, czy zmienne słowo kluczowe powinno być również używane dla nie-prymitywów. Mam element klasy, który jest ustawiony/przypisany przez jeden wątek i dostęp do innego wątku. Czy powinienem zadeklarować, że ten członek jest niestabilny?java - słowo kluczowe volatile również dla nie-prymitywów

private /* volatile */ Object o; 

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

public Object getMember() { 
    return o; 
} 

Tutaj setMember (...) jest wywoływany przez jeden wątek, a getMember() jest wywoływany przez inny.

Jeśli na przykład był to boolean, odpowiedź brzmiałaby tak.

Używam Java 1.4, a członek w tym przypadku jest tylko do odczytu. Dlatego dbam tylko o widoczność w tym przypadku, stąd moje pytanie dotyczące zmiennego słowa kluczowego.

Odpowiedz

11

Tak - volatile ma dokładnie takie samo znaczenie dla pól typu odniesienia, które ma dla pól typu pierwotnego. Z wyjątkiem tego, że w przypadku typów referencji, elementy obiektu, do którego odnosi się pole, muszą być również zaprojektowane dla dostępu wielowątkowego.

+0

Tylko ciekaw tego oświadczenia - członków obiektu pole dotyczy muszą być również przeznaczone do wielowątkowych dostępu - byłoby wspaniale, gdyby można poszerzyć, dlaczego tak jest? – jtkSource

+0

@jtkSource: volatile dotyczy tylko pola, ale pole zawiera tylko odwołanie. Tak zmienna zapewnia, że ​​inne wątki widzą aktualizacje tego odniesienia, ale jeśli wskazany obiekt nie używa poprawnie lotnej lub synchronizującej poprawnie, to inne wątki mogą nie widzieć aktualizacji pól tego obiektu. –

+0

po prostu myślenie - więc czy zmienna lotna odnosi się do obiektu, czy zmienne nielotne również nie będą "widzialne" w spójny sposób w kontekście obiektu, który zadeklarował, że jest niestabilny? Jeśli istnieją inne obiekty, które również odnoszą się do tego "odnoszącego się do obiektu" w sposób nieulotny, czy tylko te obiekty mogą nie widzieć zmiennej w stanie zgodnym? czy jest szansa, że ​​w pamięci są dwie reprezentacje tego samego obiektu? - Daj mi znać, jeśli pomieszam moją logikę. – jtkSource

6

Możesz, i może być pomocny, ale pamiętaj, że słowo kluczowe odnosi się tylko do ustawienia odniesienia. Nie ma wpływu na widoczność wielowątkową właściwości wewnątrz tego obiektu. Jeśli jest to stan, prawdopodobnie i tak chcesz zsynchronizować każdy dostęp do niego, aby zapewnić pożądane kontakty z wcześniejszymi zdarzeniami.

4

Tak, Twój kod jest prawidłowy. W tym przypadku samo odniesienie jest niestabilne, więc szanse na odniesienie są automatycznie widoczne we wszystkich innych wątkach, ale nie zmiany w odwoływanym obiekcie.

0

Jeśli przyjrzymy się AtomicInteger klasy, które uznała value jak volatile, dzięki czemu może być stosowany w środowisku wielowątkowym bez problemu cache wątek.

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; 
    } 

} 

Ale jeśli myślisz, że odniesienie do AtomicInteger nim półce zostaną zmienione z różnych przedmiotów AtomicInteger przez wielu wątków; to też potrzebujesz lotnego dla tego odniesienia.

private volatile AtomicInteger reference = new AtomicInteger(0); 

W większości przypadków tak się nie stanie; zmieni się tylko wartość obiektu; dlatego deklaruj to jako ostateczne.

private final AtomicInteger reference = new AtomicInteger(0);