Кто-то может "по-народному" объяснить значение ключевого слова volatile?
it0n00b
25 уровень
VOLATILE
Решен
Комментарии (8)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Дмитрий
12 июня 2020, 17:57
Я могу объяснить как написано в документации Oracle.
Есть вот такой кусок кода
И компилятор(!!!) может оптимизировать вот до такого
И всё прекрасно, кроме одного - эту переменную могут изменять другие потоки.
А тебе как раз эту переменную "а" и надо изменять в других потоках
Указывая слово volatile ты говоришь "компилятору", что мол братан, нефиг там баламутить, давай оставляй так, как я написал, ведь эту переменную (а) могут изменять другие потоки. Ты всё мне испоганишь!!
И компилятор такой "воу воу, хорошечно! Оставляю так, как ты написал".
Дополнительно отмечу, что читал ещё (но не в офф документации), что каждый поток живет в своём контексте (в своих переменных), то есть компилятор (опять же!!!) может сказать, чтобы другие потоки для скорости сделали копии этих переменных "а" и работали как ни в чем себе не бывало каждый в своём болотце. Volatile говорит: "Нет! Верни эту переменную в общее место хранение! Переменная "а" должна быть одна! И мне нас**ать на скорость работы!". Тут компилятор затыкается и все потоки работают с одной общей переменной "а" +3
Владислав Backend Developer
3 апреля 2020, 21:21полезный
Попробую рассказать то, о чем знаю я.
Все знают, что внутри процессора имеются области с памятью (кэш 1-го, 2-го, 3-го уровней... многие слышали про это). В эту память значения наших переменных записываются с той целью, чтобы программа могла обращаться к ним максимально быстро.
С другой стороны, имеется более медленная память - оперативная.
Далее идет самая медленная память во всей этой цепочке - внутреннее хранилище компьютера (ссд, hdd накопители). Так вот, volatile переменные хранятся не в кэше процессора, не в оперативной памяти, а аж во внутреннем накопителе!
Тем самым достигается то, что эта переменная одна для всех ядер, она не находится в памяти одного из четырех ядер, она общая для всех, и каждое ядро, при повторном обращении к этой переменной, проверяет, а не изменилось ли значение этой переменной после того, как я ее использовал в последний раз? Не изменило ли ее какое-то другое ядро, пока я занимался другими делами?
Собственно, это слово не дает одному ядру работать с этой переменной, если ей занимается другое ядро.
+7
Владислав Backend Developer
3 апреля 2020, 21:29решение
Хочу еще добавить, что «нити» (потоки) - это вещь условная, если ядро в компьютере одно. То бишь, 10 потоков на одном ядре будут работать также, как и 1 поток. Но вот если будет хотя бы 2 ядра, то каждый момент времени процессор будет заниматься двумя потоками одновременно, а остальные 8 потоков будут ждать своей очереди. Процессор поработает с двумя первыми потоками, затем освободит ядра для двух других потоков. И так далее. Volatile обеспечит то, что оба потока одновременно эту переменную изменить не смогут.
Отсюда растет проблема падения производительности.
+2
Wladyslaw Java Developer Master
3 апреля 2020, 21:44
только на винты\ссдшники никакие данные сами по себе не выгружаются. Все твои переменные - они в оперативке.
+5
Владислав Backend Developer
4 апреля 2020, 06:51
Вот как, значит, напутал и ввел человека в заблуждение. Буду знать, спасибо)
0
Wladyslaw Java Developer Master
3 апреля 2020, 21:06полезный
По народному тут не выйдет, я думаю.
В общем случае - гарантирует что значение переменной будет вычитано из основной памяти, а не из кешей и вычитано атомарно.
После 5-й джавы там еще у чтения\записи volatile переменных формируется отношение happens before.
Но это трудный вопрос, на самом деле и я сам не уверен что правильно все понимаю.
+3
it0n00b
3 апреля 2020, 21:17
правильно ли я понимаю, что в контексте данной задачи, если два потока работают одновременно и использую общую переменную и имеют возможность ее изменять, то при каждом обращении к этой переменной поток будет видеть не изначальное ее значение а то которое установил "коллега" поток до него?
+1
Владислав Backend Developer
3 апреля 2020, 21:35
Да, абсолютно верная формулировка)
+1