2013-03-18 4 views
5

Если вы объявляете переменную-член как изменчивую в Java, означает ли это, что все данные объекта хранятся в энергозависимой памяти или что ссылка на объект хранится в энергозависимой памяти?Объявление объекта как изменчивого

Например, если у меня есть следующий класс:

class C{ 
    int i = 0; 
    char c = 'c'; 
} 

Если я объявить экземпляр этого следующим образом:

private volatile C obj; 

делает, которые хранят ссылку на obj в энергозависимой памяти, или obj (obj.i и obj.c) в volatile памяти?

Это делает obj.c и obj.i нить безопасной или нет?

+2

Учебное пособие по Java SE 6 не указывает ключевое слово 'volatile' как хранилище в энергозависимой памяти, но гарантирует, что чтение и запись являются атомарными. http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html – gerrytan

+0

Все переменные хранятся в энергозависимой памяти (т. е. ОЗУ) независимо от модификатора 'volatile'. http://en.wikipedia.org/wiki/Volatile_memory –

+0

@gerrytan volatile - это не столько атомарность, сколько видимость. – assylias

ответ

8

Да только ссылка на объект будет считаться летучим в JVM, а не объект данные, которые будут находиться в куче. Если требуется переменные-члены объекта в куче летучими вы можете, конечно, применить ключевое слово для этих примитивов

class C { 
    volatile int i = 0; 
    volatile char c = 'c'; 
} 

Re: Ваш вопрос это делает ли переменные поточно, зависит от того, как вы используя переменную. Как отметил @gerrytan из документов Oracle, ключевое слово volatile помогает при чтении или записи быть атомарным, однако следует предупредить, что это не то же самое, что он всегда является потокобезопасным. Рассмотрим следующий код ...

if(obj != null) { 
    obj.doSomething(); 
} 

Это все еще возможно, что поток, который выполняет проверку нулевой, прерывается перед выполнением obj.doSomething(), а другой поток устанавливает obj = null. Здесь необходим другой механизм, такой как блок synchronized.

+0

отличный indepath ответ :) спасибо! – user965369

3
private volatile C obj; 

Это сделает только obj изменчивым.

Это делает obj.c и obj.i потоком безопасным или нет?

Нет. Чтобы сделать их потокобезопасными, вам необходимо синхронизировать доступ к ним.

+1

Это отражает общий принцип, согласно которому _instances_ класса не являются потокобезопасными или нет; _classes_ являются потокобезопасными или нет. –

2

Это сделало бы ссылку на объект volatile. Для того, чтобы сделать obj.i и obj.c также летучий вы должны сделать их летучий явно

class C{ 
    volatile int i = 0; 
    volatile char c = 'c'; 
} 
1

Если вы объявляете переменную-член как изменчивую в Java, означает ли это, что все данные объекта хранятся в энергозависимой памяти или что ссылка на объект хранится в энергозависимой памяти?

Когда мы объявляем объект изменчивым, мы на самом деле говорим базовому процессору, как работать с volatile Object.Когда он считывается инструкцией CPU, новая копия вызывается из кучи и каждый раз, когда запись выполняется на объект сохраняется в кучу и доступен для других потоков.Таким образом, процессор не выбирает старое значение кэша, ни он не записывает в кеш, и ожидает, что кеш будет записан обратно в кучу.

Это делает obj.c и obj.i потоком безопасным или нет? Нет. Это просто гарантии, что вы всегда будете иметь новую копию, когда будете читать объект. И очень хорошо, что, используя логику переменной и обработки, основанную на переменном значении, кто-то мог изменить значение в фоновом режиме и когда вы обновили его, вы обновляете другое значение.

Смежные вопросы