2016-02-03 4 views
3

Если переменная типа Int (целое число) является по своей сути атомное в Java согласно выдержке Effective Java в ниже, то почему мы видим противоречивое состояние целого значения в примере: https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.htmlJava атомная функция против Эффективное Java выдержке

Спецификация языка гарантирует, что чтение или запись переменной атома, если переменная имеет тип long или double [JLS, 17.4.7]. Другими словами, , читающий переменную, отличную от длинной или двойной, гарантированно возвращает значение, которое было записано в эту переменную некоторым потоком, даже если несколько потоков изменяют переменную одновременно и без синхронизации.

Вышеуказанные пункты противоречат мне.

ответ

5

Ваша ошибка заключается в приравнивании отдельных операций, таких как считывание значения и запись значения в операцию, например, приращение, что требует нескольких операций.

В примере, на который вы ссылаетесь, содержатся примеры приращения и уменьшения переменной int. Эти операции выглядят как одна операция в коде, но они действительно две операции за кулисами. Чтобы увеличить или уменьшить, вы должны прочитать значение, изменить его, а затем записать значение.

Эти операции должны быть синхронизированы, чтобы быть потокобезопасными, поскольку они состоят из нескольких операций, которые в случае прерывания приводят к неправильным значениям из-за условий гонки.

Даже если отдельные операции чтения или записи сами по себе согласованы, для обеспечения согласованности необходимо синхронизировать набор нескольких операций.

+0

Я думаю, что я получил лучшее понимание после прочтения ваших ответов: int is atomic, означает, что операция чтения битов целочисленной переменной является атомарной, правильно? так записывает биты обратно в целочисленную переменную. Однако после того, как я прочитал биты, выполнение приращений или декрементов вызовет противоречивые представления, поскольку многие потоки могут выполняться в разное время процессора. Правильно? –

+1

Да, каждое отдельное чтение или запись является атомарным, но приращение и декремент не являются атомарными. Поток может прервать другой поток, который только что прочитал его значение, выполнив его изменение, но когда исходный поток завершит свою работу, изменение прерывистого потока будет потеряно без внешней синхронизации. – rgettman

1

Чтение/запись в int одиночный атомарной операцией:

int a = 10; // writing 
doSomething(a); // reading 

С другой отчетности рук, увеличивающие и уменьшающие состоят из нескольких операций:

a++; 

эквивалентно:

a = a + 1; // reading and writing 

a может быть изменен после readi ng второй a и перед тем, как записать итоговое значение в первое a.

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