интернирование не потоковых безопасных вариантов строк и статических инициализаторов - PullRequest
2 голосов
/ 30 января 2012

Я пишу переводчик, и у меня довольно много строковых литералов java, которые используются переводчиком.У меня есть свой собственный неблокирующий потокобезопасный токенизатор, который быстрее, чем java.util.regex.Matcher для сложных задач, и в отличие от класса Matcher, является неизменным, так что мой токенизатор / Matcher может использоваться совместно, как неизменный конечный класс, среди нескольких потоков, которыевыполняем перевод.

Классу matcher нужен специальный строковый класс, который похож на CharSequence, но настроен на мой токенизатор.Один подкласс моего sequence / stringvariant, который построен из java.lang.String, является неизменным, и поэтому мой единственный синглтон-транслятор, совместно используемый несколькими потоками, имеет внутреннюю хэш-карту, которая отображает String в MyString.Я хочу интернировать свои неизменяемые строковые варианты, которые используются в моем неизменяемом токенизаторе, потому что многие литералы одинаковы.

Итак, у меня есть один интернирующий хэш-файл, но, к сожалению, он добавляется статическими инициализаторами несколькихдругие классы, и поэтому это звучит как карта, которая не является потокобезопасной.Как я могу постепенно построить эту интернированную карту, не получая из нее блок?Я также не хочу использовать неблокирующую параллельную хэш-карту.Гол, просто хэш-карта.

Энди

1 Ответ

0 голосов
/ 31 января 2012

к нему добавляются статические инициализаторы нескольких других классов,

Это проблема, по крайней мере, в Java 6. Согласно "Проблемы инициализации для Java"

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

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

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

...