Первый вопрос:
Will переназначение инструкций произойдет в однотридовом исполнении?
Ответ:
Изменение порядка команд является оптимизация компилятора. Порядок инструкций в одном потоке будет таким же, независимо от того, сколько потоков задействовано. Или: Да и в одном потоке.
Второй вопрос:
Почему это могло привести к проблеме в многопоточности, но не с одной нитью?
Ответ:
Правила этого переназначения предназначены для гарантирую, что нет никаких странных эффектов в однотридовой или правильно синхронизированного кода. Это означает: если мы пишем код, который не является ни одним, ни правильно синхронизированным, могут быть странные эффекты, и мы должны понимать правила и стараться избегать этих эффектов.
Итак, как сказал автор оригинального блога: Не пытайтесь, если вы действительно не уверены в понимании этих правил. И каждый компилятор будет протестирован, чтобы не разорвать String.hashCode(), но компиляторы не будут протестированы с вашим кодом.
Edit: Третий вопрос:
И снова, что на самом деле происходит?
Ответ:
Когда мы смотрим на код, он будет иметь дело хорошо с не видя изменения другого thread.So первое, что мы должны понять: метод не возвращает переменную, ни constanst ни буква. Нет способа вернуть то, что находится поверх стека, когда счетчик программ сброшен. Это должно быть инициализировано в некоторый момент времени, и оно может быть перезаписано позже. Это означает, что он может быть сначала инициализирован содержимым hash
(0 сейчас), затем другой поток заканчивает вычисление и устанавливает hash
на что-то, а затем происходит проверка hash == 0
. В свою очередь, возвращаемое значение больше не перезаписывается и возвращается 0.
Итак, точка: возвращаемое значение может изменяться независимо от возвращаемой переменной, так как это не то же самое. Современный язык программирования делает его похожим на то, чтобы сделать нашу жизнь проще. Но эта абстракция как целостность, когда вы не придерживаетесь правил.
Это проблема многопоточности. –
Him @MarkoTopolnik, Как можно выполнить переупорядочение в многопоточном режиме? Я не уверен, но я думаю, что ** переупорядочение ** выполняется в байт-коде, который ничего не делает с потоками? – MrROY
Переупорядочение определенно не происходит на уровне байт-кода; это проблема, связанная с компилятором JIT. Вы гарантированно должны иметь нормальное поведение внутри одного потока. –