Java Thread,它的答案是什么?

时间:2010-09-28 09:14:22

标签: java multithreading string

问题来自http://www.javacertifications.net/javacert/scjp1.6Mock.jsp

问题没有-20

以下代码的输出是什么?

public class Test extends Thread
{   
    static String sName = "good";
    public static void main(String argv[])
    {
        Test t = new Test();
        t.nameTest(sName);
        System.out.println(sName);    
    }
    public void nameTest(String sName)
    {
        sName = sName + " idea ";
        start();
    }
    public void run()
    {
        for(int i=0;i  <  4; i++)
        {
            sName = sName + " " + i;

        }
    }
}

选项     一个好的     B)好主意     C)好主意好主意     正确答案是:A

解释:在String的情况下,本地方法中的更改值不会在全局变化(因为String对象是不可变的)。

8 个答案:

答案 0 :(得分:8)

没有一个答案是正确的,也没有一个正确答案。

问题非常糟糕,因为它混合了两个完全不同的问题:

  • sName方法的nameTest()参数隐藏了同名的静态变量,对局部变量的更改无效。
  • nameTest()启动一个线程,该线程在其run()方法中更改静态变量,main()方法打印变量而不等待该线程完成。这被称为竞争条件:将打印变量的状态非常巧合 - 以下任何一种情况都是可能的:
    • good 0
    • good 0 1
    • good 0 1 2
    • good 0 1 2 3

答案 1 :(得分:3)

请注意,方法nameTest有一个参数String sName,它有效地隐藏了具有相同名称的static类成员。这一行

sName = sName + " idea ";

指的是修改本地方法参数而不是static类成员。要从方法中访问类成员,应使用类名限定,即Test.sName

run方法中,static sName成员被修改,但最终它变成了“good 0 1 2 3”。但是,主线程(隐式)启动线程t然后打印sName的值,以及修改相同值的子线程之间存在竞争条件 。由于不涉及同步,所以主线程完全有可能在之前打印值,然后由另一个线程(即“好”)修改它。结果也可能是“好0”,“好0 1”等。但是,在所有这些中,仅列出了“好”。所以 A是唯一可能的答案

答案 2 :(得分:1)

答案是这个方法:

public void nameTest(String sName){
        sName = sName + " idea ";
         start();
}

在那里,sName上的分配是指输入参数sName,而不是静态值Test.sName

因此,当您使用run()方法访问静态成员时,您将获得初始值("good"

答案 3 :(得分:1)

方法nameTest正在修改本地参数sName而不是静态参数。因此输出是“好”。

为了修改静态参数,我认为您需要使用Test.sName

答案 4 :(得分:0)

在这种情况下,nameTest方法中存在陷阱。请注意,方法参数名称与静态变量名称相同。

在Java中,变量解析表明在这种情况下,访问参数,静态变量为“hidden”。如果要访问静态变量,则必须使用Test.sName

因此,在此示例中,“idea”永远不会附加到静态sName变量。唯一没有包含“想法”的答案是A,所以1是个好答案。

答案 5 :(得分:0)

这将输出'good' 当你调用nameTest(sName)时,你只传递一个引用的副本,所以任何更改,所以在nameTest的上下文中你正在处理另一个变量。这意味着任何重新分配此变量的尝试都不会影响nameTest外部。全局静态变量sName也被参数sName隐藏。 如果string不是不可变的,那么就可以对它们进行更改。

答案 6 :(得分:0)

在方法中,您始终处理本地参考COPY(如果您将其作为arg提供)。你更改了引用COPY,但源仍然相同。 答案可以是goodgood 0good 0 1等。

答案 7 :(得分:0)

实际运行程序返回

好0 1 2 3

(实际写出来并尝试在java中运行它......你应该尝试一下)。

通过该计划,我们可以这样想:

在函数nameTest中,sName是一个本地String变量。

就像解释说的那样,字符串是不可变的,因此使用“idea”进行字符串连接将创建字符串的新实例 - “好主意” - 并将其分配给局部变量sName。类变量sName(我认为调用它不应该被称为全局)将作为结果保持“良好”。

然后继续使用start()运行线程函数 - 它调用run()。

在函数run()中,我们再次进行连接,但这次我们分配给类变量sName。

因此,当run()函数返回时,类变量sName被更改,打印输出将反映出来。