Недавно я много читал здесь, в SO, и в других местах об управлении многопоточной памятью, в частности, об использовании ключевого слова volatile
. Я начинаю чувствовать себя достаточно уверенно в концепции, однако, чтобы в полной мере оценить эффект, который она оказывает, я хотел бы попытаться провести несколько экспериментов, которые ее иллюстрируют.
Вот моя настройка: у меня есть поток производителя (он считывает аудиоданные с микрофона, связанные с моим предыдущий вопрос, но фактические данные не имеют значения), который передает данные как byte[]
в отдельный поток-потребитель. Способ, которым данные распределяются между потоками, является основной переменной в моем эксперименте: я пробовал ArrayBlockingQueue
; Я попробовал общую volatile byte[]
ссылку (с array = array
ссылкой на себя, как рекомендовано в эта запись в блоге); и я также пробовал обычный энергонезависимый byte[]
без ссылки на себя. Оба потока также записывают данные на диск по мере их выполнения.
Я надеялся обнаружить, что после запуска в течение некоторого времени энергонезависимая версия byte[]
будет иметь несоответствия между данными, которые производитель пытался передать, и данными, которые читал потребитель из-за того, что некоторые записи памяти не видны в памяти. время, в то время как две другие версии будут иметь точно такие же данные, регистрируемые каждым потоком, из-за мер предосторожности, принятых для обеспечения публикации записей памяти. Однако, как бы то ни было, я нахожу 100% точность, какой бы метод я ни использовал.
Я уже могу придумать несколько вариантов того, почему это произошло, но мой главный вопрос заключается в следующем: при каких условиях выполняется запись в энергонезависимую переменную, невидимую для другого потока, что, насколько я понимаю, весь смысл volatile
? И могу ли я форсировать эти условия в экспериментальных целях?
Мои мысли пока такие:
- Может быть, два потока работают на одном ядре и используют один и тот же кеш, поэтому записи в память видны сразу?
- Может быть, загрузка процессора является фактором? Возможно, мне нужно много потоков, выполняющих разные задачи, прежде чем я увижу какую-либо проблему?
- Может быть, мне нужно подождать дольше: возможно, такие проблемы очень редки?
Может ли кто-нибудь предложить, как я мог спланировать такой эксперимент, или объяснить, почему моя идея ошибочна?
Большое спасибо.
volatile
на однопроцессорных машинах — предотвратить переупорядочивание команд. Если вы тщательно обдумаете это, вы можете заставить компилятор что-то переупорядочить, чтобы вы могли наблюдать записи, которые происходят в порядке, отличном от того, который вы написали. - person Giulio Franco   schedule 28.08.2013