Пул String принимает локальные переменные? - PullRequest
0 голосов
/ 14 декабря 2009

Я полагал, что пул строк забросил локальные строки, когда их методы завершены

Тем не менее:

public class TestPool implements Runnable{

    /**
     * @param args the command line arguments
     */
    public void run() {
        String str= "hello";
        synchronized(str){

            try {
                System.out.print(Thread.currentThread().getName());
                Thread.sleep(500);
                System.out.print(Thread.currentThread().getName());
            }

            catch(InterruptedException e){

            }

        }
         }
        public static void main(String []args){
            new Thread(new TestPool(),"A").start();
            new Thread(new TestPool(),"B").start();
        }
    }

Согласно руководству Whizlabs, этот код корректно синхронизирует свои потоки на основе локальной строки. Выход всегда будет AABB или BBAA. Зачем? Почему str String переживает свою локальную декларацию?

Ответы [ 4 ]

3 голосов
/ 14 декабря 2009

Да, str является только локальной переменной, но она указывает на пул строк; при двух последовательных вызовах метода str будет указывать на одно и то же место в пуле, поэтому вы все еще будете синхронизироваться с одним и тем же объектом.

Если ваш код был

String str = new String("hello");

тогда вы действительно будете синхронизироваться с локальным объектом.

3 голосов
/ 14 декабря 2009

Поскольку оба локальных объявления str указывают на один и тот же внутренний строковый литерал "hello". Внутренние строки являются константами и поддерживаются в пуле. Они не имеют типичного жизненного цикла и, следовательно, не собирают мусор, когда больше нет ссылок.

Это не было бы так, если бы объявление было

String str = new String("hello");
2 голосов
/ 14 декабря 2009

str - это локальная переменная, область действия которой ограничена методом run(), в котором она определена. Для разных потоков должны быть разные str s.

Однако, оба этих различных локальных str s указывают на строку "hello", которая в качестве константы времени компиляции равна interned . То есть один экземпляр String с таким содержимым создается в пуле, и все, что указывает на один и тот же набор символов, будет указывать на этот же объект.

Это как если бы вы создали статический экземпляр такой строки.

0 голосов
/ 14 декабря 2009

Дело не в том, что пул строк принимает локальные переменные, а в том, что "hello" сохраняется только один раз и используется повторно (поскольку строки являются неизменяемыми).

Попробуйте это внутри синхронизированного блока, оба потока напечатают одно и то же значение, указывая, что у вас один и тот же объект.

System.out.println( str.hashCode() );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...