2015-01-30 4 views
1

У меня есть переменная, которую мне нужно установить для значения, которое я хочу, чтобы поток был видимым. Я понятия не имею, какой поток выполняет чтение.Неизменяемая многопоточная запись, которая является видимой нитью

Переменная устанавливается только один раз, установив ее как volatile. Я предотвращаю чтение значения переменной из кэша ЦП (или так я понимаю). Напишите один раз, прочитайте много.

Я не могу получить эту переменную в конструкторе, чтобы использовать final.

Мой грубый поток:

thread 1: set value x 
thread 1: fire notification to say x is ready. 
thread 2: read x. 

Я понимаю, что я могу сделать следующее:

public void setX(int value) { 
    Object o = new Object(); 
    synchronized(o) { 
     this.x = value; 
    } 
} 

И из-за происходит, прежде чем принцип, то значение будет выписана в память , Это верно?

+0

Что вы пытаетесь достичь снова? возможно, вам просто нужен синглтон – djb

+0

'synchronized (o)' не _happen before_ ничего в вашем примере, потому что 'o' ссылается на другой объект каждый раз, когда вызывается' setX() '. Синхронизация означает только что-либо, когда два или более потоков синхронизируются на _same_-объекте. –

+0

@Cheetah Я понимаю, что поток 2 должен ждать, пока 'x' не будет установлен в потоке 1, однако я хотел бы знать, должен ли поток 1 также ждать, пока поток 2 не захочет читать' x' ... –

ответ

1

Не устанавливайте его на volatile. В качестве правила большого пальца используйте значение volatile, если значение этой переменной меняется, и несколько потоков читают/записывают эту переменную. В вашем случае вы хотите, чтобы чтения были кэшированы. потому что значение x не изменится. Использование volatile will снижение производительности В вашем случае вам просто нужно убедиться, что set() происходит до get(). На самом деле это произойдет, потому что если someThread уведомляет другой поток, другой поток не будет считывать значение x.

PS: Я предполагаю, что другая нить (-и) не будет читать значение x, если только не будет уведомлено. Дайте мне знать, если я ошибаюсь.

+0

Конечно, значение все равно может сидеть в кеше. – Cheetah

+0

@Cheetah - Ваши потоки будут читать это значение * без уведомления *? – TheLostMind

+0

Нет, но уверен, что если его нестабильная и нить 1 задает значение x, это значение может не быть записано в память по времени, когда поток 2 получает уведомление, которое он может читать .... – Cheetah

0

Синхронизация объекта, созданного в методе, бессмысленна. Как вы, notify(), все темы для чтения - это вопрос, на который вы должны ответить самому - намереваетесь ли вы их получить wait() ing для этого уведомления? Я бы посоветовал вернуть null или от геттера, если значение еще не установлено ...

+0

он не пытается уведомить .... он только хочет убедиться, что 'x' обязательно синхронизируется с« основной »памятью. однако я согласен, что просто создать объект для этого не обязательно, мы можем использовать 'this'. – sodik

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