2017-04-23 72 views
0

所以我想将参数传递给我的线程,而且我的输出结果并不如预期。下面是我的代码:将参数传递给线程方法时输出结果不同

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 

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

回答

1

如果你改变

static int c; 

private int c; 

既然你不访问变量c出你的类的,没有任何理由应该是静态的。如果你把它变成静态的,每次你改变它,它就是最后一个值。

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

0

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

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

+0

你能更具体一点吗?就像我如何获得理想的输出? – user227666

+0

我真的不知道我怎么可以更具体。 –

0

我只是重新排序在main方法的线,这里的区别是

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 希望这会清除你对静态变量的疑惑

0

你问你是否看到的问题是由线程干扰引起的。在发布的程序中没有线程干扰的可能性,因为只有一个线程。在Runnable上调用run可以在当前线程中执行它。

如果你想创建一个新的线程来执行您的每一个的Runnable,那么你应该更改代码以

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

,然后你将有多个线程的程序。此时,不能保证一个线程将在另一个线程之前打印其输出。

为了证实这一点,你可以行

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

添加到每个run方法的主体和主要方法。如果他们都打印相同的名称,那么你不会创建任何线程。

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