将参数传递给 Java 线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20640896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing parameters to Java Thread
提问by Juntae
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 ? I think that should be 3000. Maybe the variable "int c" isn't dispatch to run() method. How can I solve this issue?
为什么这个结果是 0 ?我认为这应该是 3000。也许变量“int c”不是调度到 run() 方法。我该如何解决这个问题?
采纳答案by Bob Kuhar
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. That is to stay, if you have 2 separate ThreadParams going simultaneously, one of them is likely present the "wrong" value for C. Consider...
我认为“static int c”的选择是不正确的,因为它意味着 ThreadParam 的所有实例都将“共享”(并且在这方面很糟糕)c 的一个共同值。也就是说,如果您有 2 个单独的 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.
}
}
If you make the "c" local to the instance, you overcome the "2 separate ThreadParams are affecting the same value" problem. If you make the "private int c" final, you are avoiding the need for synchronization. If you need to mutate "c" down in the run (or from the outside), now you are entering the world of synchronization...
如果将“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() );
}
}
Other than that, tuxdna's is correct in describing how you "pass params to a Runnable". The Runnable is inconsequential; 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.
除此之外,tuxdna 在描述如何“将参数传递给 Runnable”方面是正确的。Runnable 无关紧要;您正在将参数传递给一个类(但是您实现了这一点)。如果您需要它们在 run() 中可用,则需要注意同步。
回答by Andrew Logvinov
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
。
回答by Xavier Coulon
Your 'c' variable is defined twice: once at the class level (with a static modifier) and once in the ThreadParam constructor. Remove the 'static' on the class field and remove the 'int' inside the constructor.
您的 'c' 变量定义了两次:一次在类级别(使用静态修饰符),一次在 ThreadParam 构造函数中。删除类字段上的 'static' 并删除构造函数中的 'int'。
回答by Xavier Delamotte
c
should not be static and should be assigned in your constructor.
In your example, you've assigned to a variable c
, not the field.
c
不应该是静态的,应该在你的构造函数中分配。在您的示例中,您已分配给变量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);
}
}
回答by tuxdna
Runnable is only an interface that requires you to define a run()
method, nothing more nor less. 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.
Runnable 只是一个需要你定义run()
方法的接口,不多也不少。因此,本质上,您可以以任何您想要的方式(您传递两个整数a
和b
)自由地声明您的类构造函数,以便能够从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
)