Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将参数传递给线程方法时,输出结果不同_Java_Multithreading_Static - Fatal编程技术网

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

Java 将参数传递给线程方法时,输出结果不同,java,multithreading,static,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

因此,我试图将参数传递给我的线程,而我的输出并不像预期的那样。下面是我的代码:

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

那么这是一个线程干扰的问题吗?有人能解释为什么会发生这种情况吗?

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

您可能希望它成为一个实例变量。

如果您更改了它该怎么办

static int c;

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


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

我刚刚对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
请看这篇文章以及&
希望这将消除您对静态变量的疑虑,您询问您看到的问题是否是由线程干扰引起的。在发布的程序中没有线程干扰的可能性,因为只有一个线程

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

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

new Thread(shouldBe3).start();
new Thread(shouldBe15).start();
然后你会有一个多线程的程序。在这一点上,无法保证一个线程将在另一个线程之前打印其输出

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

System.out.println(Thread.currentThread().getName());
每个run方法的主体和main方法。如果它们都打印相同的名称,那么您不会创建任何线程


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

您能更具体一点吗?比如说,我怎样才能得到期望的输出?我真的不知道我怎样才能更具体。
System.out.println(Thread.currentThread().getName());