将参数传递给线程方法时输出结果不同

时间:2017-04-23 21:46:34

标签: java multithreading static

所以我试图将参数传递给我的线程,我的输出不是预期的。以下是我的代码:

class BadThreadParam implements Runnable {
    static int c;

    public BadThreadParam( int a, int b ) {
        c = a + b;
    }

    public void run() {
        System.out.println( c );
    }
}

public class BadThreadParamTest {
    public static void main( String[] args ) {
       BadThreadParam shouldBe3 = new BadThreadParam( 1, 2 );
       BadThreadParam shouldBe5 = new BadThreadParam( 3, 12 );
       shouldBe3.run();  // Expect 3 but is 15.  WTF?
       shouldBe5.run();  // Expect 15.
    }
}

我期待的最终输出是:

3
15

但我得到了:

15
15

这是线程干扰的问题吗?任何人都可以解释为什么会这样吗?

4 个答案:

答案 0 :(得分:1)

如果您更改

,该怎么办?
static int c;

private int c;

由于您没有从类中访问变量c,因此没有理由它应该是静态的。如果您将其设置为静态,则每次更改它时,它都将是最后一个值。

如果将其更改为private,则它是一个'instance'变量,它链接到您使用新BadThreadParam()创建的实例;所以输出是给特定实例的值。

答案 1 :(得分:0)

c是一个静态变量。这意味着当一个线程更改它时,它会为每个人更改。

您可能打算将它作为实例变量。

答案 2 :(得分:0)

我刚刚在主方法中重新排序了这些行,这就是差异

public static void main(String[] args) {
    BadThreadParam shouldBe3 = new BadThreadParam(1, 2);
    shouldBe3.run();
    BadThreadParam shouldBe5 = new BadThreadParam(3, 12);
    shouldBe5.run(); 
}

这是输出

3
15

看看这个以及@JC97&发布的答案。 @Joe C 希望这能清除你对静态变量的怀疑

答案 3 :(得分:0)

您询问您所看到的问题是否是由线程干扰引起的。发布的程序中不存在线程干扰的可能性,因为只有一个线程

你正在Runnable上调用run,它在当前线程中执行它。

如果您想创建一个新线程来执行每个Runnables,那么您应该将代码更改为

new Thread(shouldBe3).start();
new Thread(shouldBe15).start();

然后你将拥有一个包含多个线程的程序。此时,将无法保证一个线程将在另一个线程之前打印其输出。

要确认这一点,您可以添加

System.out.println(Thread.currentThread().getName());

到每个run方法的主体和main方法。如果它们都打印了相同的名称,那么您就不会创建任何线程。

正如其他答案所说,你让第二个构造函数调用覆盖第一个构造函数调用所设置的c的内容。 static关键字表示变量属于类,而不属于任何一个实例,并且所有实例都访问同一个变量。 c应该是一个实例变量(删除静态关键字),以便每个Runnable对象都有自己的副本。