2009-12-14 2 views
0

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

Еще:

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', этот код correcly синхронизации своих тема на основе локальной String. Выход всегда будет AABB или BBAA. Зачем? Почему str String переживает локальную декларацию?

ответ

3

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

Это не было бы в случае, если заявление было

String str = new String("hello"); 
2

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

Однако оба этих различных местные str сек точки в строках «Привет», который, как время компиляции постоянная, является интернирован. То есть, один экземпляр String с этим контентом создается в пуле, и все, что указывает на один и тот же пробег символов, будет указывать на тот же объект.

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

+0

+1 для "(обновление) - вернитесь назад!"? –

+0

Я должен написать это чаще :) Надеюсь, мой окончательный текст также заслуживает голосования. –

+0

Ссылка - это локальная переменная, но String, на которую она указывает, - нет. Посмотрите, что произойдет, когда вы измените объявление на String str = new («hello»); – andandandand

3

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

Если код был

String str = new String("hello"); 

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

0

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

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

System.out.println(str.hashCode()); 
+0

Я думаю, вы противоречите себе. Строка «hello» хранится в пуле строк. Больше некуда хранить. – andandandand

+0

hashCode не является надежным для тестирования для одного и того же объекта. ... 1) разные строки могут приводить к тому же hashCode («10» и «0O») ... 2) 2 разных строки (a! = B) с тем же содержимым (a.equals (b)) должны возвращаться тот же hashCode –