简体   繁体   English

将参数传递给Java线程

[英]Passing parameters to Java Thread

I seen already : How can I pass a parameter to a Java Thread? 我已经知道: 如何将参数传递给Java线程?

But I don't know how exactly use that. 但是我不知道该怎么使用。 So I made easy samle code to save your precious time : 因此,我简化了代码示例,以节省您的宝贵时间:

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();  
}   
}

Why is this result 0 ? 为什么结果为0? I think that should be 3000. Maybe the variable "int c" isn't dispatch to run() method. 我认为应该是3000。也许变量“ int c”没有调度到run()方法。 How can I solve this issue? 我该如何解决这个问题?

I think the choice of "static int c" is incorrect as it means that all instances of ThreadParam will "share" (and poorly at that) a common value for c. 我认为“ static int c”的选择是不正确的,因为这意味着ThreadParam的所有实例都将“共享”(并且很糟糕)c的通用值。 That is to stay, if you have 2 separate ThreadParams going simultaneously, one of them is likely present the "wrong" value for C. Consider... 就是这样,如果您同时有2个单独的ThreadParam,则其中之一可能表示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.
    }
}

If you make the "c" local to the instance, you overcome the "2 separate ThreadParams are affecting the same value" problem. 如果将“ c”设置为实例本地,则可以解决“ 2个单独的ThreadParams影响相同值”的问题。 If you make the "private int c" final, you are avoiding the need for synchronization. 如果将“ private int c”定为final,则可以避免同步。 If you need to mutate "c" down in the run (or from the outside), now you are entering the world of synchronization... 如果您需要在运行中(或从外部)对“ 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() );
    }
}

Other than that, tuxdna's is correct in describing how you "pass params to a Runnable". 除此之外,tuxdna在描述您如何“将参数传递给Runnable”方面是正确的。 The Runnable is inconsequential; Runnable无关紧要; you are passing params to a class (however you achieve that). 您正在将参数传递给课程(无论您如何实现)。 If you need them available down in a run(), you need to be aware of synchronization. 如果需要它们在run()中可用,则需要注意同步。

The result is 0 because in constructor you're not actually assigning new value to static int c , but you're assigning it to local variable c . 结果为0,因为在构造函数中,您实际上并未将新值分配给static int c ,而是将其分配给局部变量c

Change int c into c in constructor. 在构造函数中将int c更改为c

c should not be static and should be assigned in your constructor. c不能是静态的,应该在构造函数中分配。 In your example, you've assigned to a variable c , not the field. 在您的示例中,您已分配给变量c ,而不是字段。

Here is the corrected code: 这是更正的代码:

class ThreadParam implements Runnable { 
private int c;

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

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

}

Your 'c' variable is defined twice: once at the class level (with a static modifier) and once in the ThreadParam constructor. 您的'c'变量定义了两次:一次在类级别(带有静态修饰符),一次在ThreadParam构造函数中。 Remove the 'static' on the class field and remove the 'int' inside the constructor. 删除类字段上的“静态”,并删除构造函数中的“ int”。

Runnable is only an interface that requires you to define a run() method, nothing more nor less. Runnable只是一个需要您定义run()方法的接口,仅此而已。 So, essentially, you are free to declare your class constructor any way you want ( you are passing two integers a and b ) to be able to access them from run() method. 因此,从本质上讲,您可以随意声明类构造函数(要传递两个整数ab ),以便能够从run()方法访问它们。

Also you are defining a local variable in the constructor that is destroyed after the constructor has finished. 另外,您还要在构造函数中定义一个局部变量,该局部变量在构造函数完成后将被销毁。 Which leaves your static int c value to be still 0 . 这样您的static int c值仍为0

Here is the fixed version: 这是固定版本:

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();
    }
}

And the output is 21000 ( and not 3000 ) 输出是21000 (而不是3000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM