в JLS 3, 17.5 Вторая часть обсуждения Final Field Semantics: http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.5
Говорят, что myS может равняться "/ tmp", я лично не могу этого понять.Кто-нибудь может дать больше объяснений?Другой момент - это то, что говорит этот пример, означает ли это, что если мы хотим разделить Global.s между многопоточными, нам нужно сделать его окончательным (если он окончательным, то не может быть изменен после построения) или нужно синхронизировать при чтении и записи?или объявить массив String длиной 1 и последний, чтобы его можно было изменить и предоставить общий доступ ??
исходное содержимое в JLS:
Рассмотрим следующий пример.Один поток (который мы будем называть потоком 1) выполняет
Global.s = "/tmp/usr".substring(4);
, в то время как другой поток (поток 2) выполняет
String myS = Global.s;
if (myS.equals("/tmp"))System.out.println(myS);
объяснение в JLS:
Строковые объекты предназначены для неизменности, и строковые операции не выполняют синхронизацию.В то время как реализация String не имеет никаких гонок данных, другой код может иметь гонки данных, включающие использование строк, и модель памяти дает слабые гарантии для программ, которые имеют гонки данных.В частности, если бы поля класса String не были окончательными, то было бы возможно (хотя и маловероятно), чтобы поток 2 мог изначально видеть значение по умолчанию 0 для смещения строкового объекта, что позволяет сравнивать его как равное "/ TMP».Более поздняя операция над объектом String может увидеть правильное смещение 4, так что объект String воспринимается как «/ usr».Многие функции безопасности языка программирования Java зависят от того, что строки считаются действительно неизменяемыми, даже если вредоносный код использует гонки данных для передачи ссылок на строки между потоками.