将参数传递给Java Thread

时间:2013-12-17 17:31:33

标签: java multithreading

我已经看过了:How can I pass a parameter to a Java Thread?

但我不知道究竟是怎么用的。因此,我制作了简单的代码来节省宝贵的时间:

class ThreadParam implements Runnable { 
static int c;

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

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

}

public class ThreadParamTest {
public static void main(String args[]){
    Runnable r = new ThreadParam(1000,2000);
    new Thread(r).start();  
}   
}

为什么这个结果为0?我认为应该是3000.也许变量“int c”不是调度run()方法。我该如何解决这个问题?

5 个答案:

答案 0 :(得分:6)

我认为“static int c”的选择是不正确的,因为这意味着ThreadParam的所有实例都将“共享”(并且很差)c的公共值。那就是留下来,如果你有两个单独的ThreadParams同时进行,其中一个可能会出现C的“错误”值。考虑......

class BadThreadParam implements Runnable {
    static int c;

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

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

class ImmutableThreadParam implements Runnable {
    private final int c;

    public ImmutableThreadParam( 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, 2 );
        shouldBe3.run();  // Expect 3 but is 5.  WTF?
        shouldBe5.run();  // Expect 5.

        ImmutableThreadParam expect3 = new ImmutableThreadParam( 1, 2 );
        ImmutableThreadParam expect5 = new ImmutableThreadParam( 3, 2 );
        expect3.run();  // Expect 3.
        expect5.run();  // Expect 5.
    }
}

如果将“c”设为本地实例,则可以克服“2个独立的ThreadParams正在影响同一个值”的问题。如果您将“private int c”设为final,则无需同步。如果您需要在运行中(或从外部)变异“c”,现在您正在进入同步世界......

class ThreadSafeMutableThreadParam implements Runnable {
    private int c;

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

    public synchronized void setC( int c ) {
        this.c = c;
    }

    public synchronized int getC() {
        return c;
    }

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

除此之外,tuxdna在描述你如何“将params传递给Runnable”方面是正确的。 Runnable无关紧要;你把params传给了一个班级(但是你实现了这个目标)。如果你需要在run()中使用它们,你需要注意同步。

答案 1 :(得分:4)

结果为0,因为在构造函数中,您实际上并没有为static int c分配新值,而是将其分配给局部变量c

在构造函数中将int c更改为c

答案 2 :(得分:4)

c不应该是静态的,应该在构造函数中指定。 在您的示例中,您已分配给变量c,而不是字段。

以下是更正后的代码:

class ThreadParam implements Runnable { 
private int c;

public ThreadParam(int a, int b){
    this.c = a+b;
}

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

}

答案 3 :(得分:3)

您的'c'变量定义了两次:一次在类级别(使用静态修饰符),一次在ThreadParam构造函数中。删除类字段上的'static'并删除构造函数中的'int'。

答案 4 :(得分:2)

Runnable只是一个需要您定义run()方法的接口,仅此而已。所以,基本上,你可以随心所欲地声明你的类构造函数(你传递两个整数ab),以便能够从run()方法访问它们。

此外,您还在构造函数中定义了一个局部变量,该变量在构造函数完成后被销毁。这使您的static int c值仍为0

这是固定版本:

class ThreadParam implements Runnable {
    private int c;

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

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

}

public class ThreadParamTest {

    public static void main(String args[]) {
        Runnable r = new ThreadParam(1000, 20000);
        new Thread(r).start();
    }
}

输出为21000(而不是3000