我已经看过了: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()方法。我该如何解决这个问题?
答案 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()
方法的接口,仅此而已。所以,基本上,你可以随心所欲地声明你的类构造函数(你传递两个整数a
和b
),以便能够从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
)