所以我试图将参数传递给我的线程,我的输出不是预期的。以下是我的代码:
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
这是线程干扰的问题吗?任何人都可以解释为什么会这样吗?
答案 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
答案 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对象都有自己的副本。