Как ведут себя строки между различными потоками и директорами классов? - PullRequest
0 голосов
/ 15 февраля 2012

В документации Java говорится, что в приведенном ниже примере условие будет истинным:

String a = new String("ABC");
String b = new String("ABC");

if (a.intern() == b.intern())
{
 ....
}

Я хотел бы знать, верно ли это, если учесть, что a и bопределены в разных Threads или даже в разных ClassLoaders?

Этот вопрос возник, когда мне понадобилась возможность синхронизировать блок, который загружает определенную конфигурацию на основе имени объекта, поэтому я хотел сделать что-то вроде:

synchronized (entityName.intern())
{
}

Я неконечно, это хорошая практика, поэтому я, вероятно, не собираюсь следовать этому направлению - но вопрос все еще меня интересует.

Ответы [ 2 ]

3 голосов
/ 15 февраля 2012

Если в разных потоках , да, условие будет истинным.

Если на разных загрузчиках классов , я бы не рассчитывал, что условие истинно. (Но действительно ли вы загружаете две копии String, используя разные загрузчики классов?) В документации сказано, что intern реализован в String с использованием собственного кэша. Из String#intern документации :

Возвращает каноническое представление для строкового объекта.

Пул строк, изначально пустой, поддерживается в частном порядке классом String.

(Мой акцент)

Итак, если вы как-то дважды загрузите класс String, используя разные загрузчики классов (я не уверен, как вы это сделаете, но держу пари, что есть способ), то каждый из классов String будет иметь свой кэш & mdash; в теории . Тем не менее, реализация может не проводить такое различие. intern - это нативный метод в Oracle JVM, использующий таблицу символов, реализованную в C ++. Я не достаточно внимательно следил за логикой, чтобы понять, будут ли два экземпляра String в одной JVM, о которых вы говорите, использовать одну и ту же таблицу символов, или нет. Но в этот момент мы смотрим на реализацию, которая может варьироваться. документация предполагает, что нет, они не будут одинаковыми.

0 голосов
/ 15 февраля 2012

Да - интернирование работает по всей JVM.

Я был бы очень обеспокоен вашей средой исполнения, если бы вы загружали несколько версий java.lang.String через разные загрузчики классов ... стажировка была бы наименьшим из ваших беспокойств.

...