【问题标题】:Does the String pool take local variables?字符串池是否采用局部变量?
【发布时间】:2009-12-14 15:55:15
【问题描述】:

我相信字符串池在方法完成后放弃了本地字符串

还是:

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 比它的本地声明更长寿?

【问题讨论】:

    标签: java string multithreading synchronization


    【解决方案1】:

    因为 str 的两个本地声明都指向同一个内部字符串字面量“hello”。内部字符串是常量并保存在池中。它们没有典型的生命周期,因此在没有引用时不会被垃圾收集。

    如果声明是这样的,情况就不会

    String str = new String("hello");
    

    【讨论】:

      【解决方案2】:

      是的,str只是一个局部变量,但它指向的是字符串池;在该方法的两次连续调用中,str 将指向池中的同一位置,因此您仍在同一个对象上进行同步。

      如果你的代码是

      String str = new String("hello");
      

      那么您确实会在本地对象上进行同步。

      【讨论】:

        【解决方案3】:

        str是一个局部变量,其作用域仅限于定义它的run()方法。对于不同的线程,应该有不同的strs。

        但是,这两个不同的本地 strs 都指向字符串“hello”,作为编译时常量,它是 interned。也就是说,在池中生成具有该内容的 String 的单个实例,并且任何指向相同字符运行的任何内容都将指向同一对象。

        就好像你已经创建了这样一个字符串的静态实例。

        【讨论】:

        • 我应该更频繁地写这个:) 希望我的最终文本也值得投票。
        • 引用是一个局部变量,但它指向的字符串不是。查看将声明更改为 String str = new ("hello"); 时会发生什么
        • 我就是这么说的。看来你明白了! :)
        【解决方案4】:

        不是字符串池取局部变量,而是"hello"只存储一次并重复使用(因为字符串是不可变的)。

        在你的同步块中试试这个,两个线程将打印相同的值,表明你有相同的对象。

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

        【讨论】:

        • 我认为你在自相矛盾。 “hello”字符串存储在字符串池中。没有其他地方可以存储它。
        • hashCode 对于测试相同的对象不可靠。 ... 1) 不同的字符串可能导致相同的 hashCode ("10" 和 "0O") ... 2) 2 个不同的字符串 (a != b) 具有相同的内容 (a.equals(b)) 必须返回相同的hashCode
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-07
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        • 2023-02-06
        • 2021-08-18
        相关资源
        最近更新 更多