向Java线程传递参数
我已经看到: 但我不知道该怎么用。因此,我制作了简单的samle代码,以节省您宝贵的时间:向Java线程传递参数,java,multithreading,Java,Multithreading,我已经看到: 但我不知道该怎么用。因此,我制作了简单的samle代码,以节省您宝贵的时间: 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 stat
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不是dispatch to run方法。如何解决此问题?结果为0,因为在构造函数中,您实际上并没有将新值赋给静态int c,而是将其赋给局部变量c
在构造函数中将int c更改为c。结果为0,因为在构造函数中,您实际上并没有将新值赋给静态int c,而是将其赋给局部变量c
在构造函数中将int c更改为c。您的“c”变量定义了两次:一次在类级别使用静态修饰符,一次在ThreadParam构造函数中。删除类字段中的“static”并删除构造函数中的“int”。您的“c”变量定义了两次:一次在类级别使用静态修饰符,一次在ThreadParam构造函数中。删除类字段中的“static”并删除构造函数中的“int”。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);
}
}
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);
}
}
Runnable只是一个接口,它要求您定义一个run方法。所以,本质上,您可以自由地以任何方式声明类构造函数,只要您传递两个整数a和b,就可以从run方法访问它们 此外,您正在构造函数中定义一个局部变量,该局部变量在构造函数完成后被销毁。这使得静态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,Runnable只是一个需要定义run方法的接口,不多也不少。所以,本质上,您可以自由地以任何方式声明类构造函数,只要您传递两个整数a和b,就可以从run方法访问它们 此外,您正在构造函数中定义一个局部变量,该局部变量在构造函数完成后被销毁。这使得静态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,我认为选择static int c是不正确的,因为这意味着ThreadParam的所有实例都将共享c的一个公共值。也就是说,如果你同时有2个线程线程,它们中的一个可能会出现错误的值。
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设置为实例的本地,则可以克服两个单独的ThreadParams影响相同值的问题。如果将私有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在描述如何将参数传递给Runnable时是正确的。可运行的是无关紧要的;您正在将参数传递给一个类,但是您实现了这一点。如果您需要它们在运行中可用,则需要注意同步。我认为选择static int c是不正确的,因为这意味着ThreadParam的所有实例都将共享c的公共值。也就是说,如果你同时有2个线程线程,它们中的一个可能会出现错误的值。
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设置为实例的本地,则可以克服两个单独的ThreadParams影响相同值的问题。如果将私有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在描述如何将参数传递给Runnable时是正确的。可运行的是无关紧要的;您正在将参数传递给一个类,但是您实现了这一点。如果您需要它们在运行中可用,则需要注意同步。您在方法ThreadParam中本地声明了c您在方法ThreadParam+1中本地声明了c,海报可能不希望c字段是静态的。这意味着ThreadParam的所有实例共享同一字段。我可以再问你一个问题吗?在我的示例代码中,在run方法中,如何打印变量a?我想展示一下。您需要在ThreadParam类@user3100921中将a存储为另一个非静态字段。然后你可以打印它。+1同样,海报不希望c字段是静态的。这意味着ThreadParam的所有实例共享同一字段。我可以再问你一个问题吗?在我的示例代码中,在run方法中,如何打印变量a?我想展示给大家看
您需要在ThreadParam类@user3100921中将a存储为另一个非静态字段。这段代码在技术上是正确的,但是静态int c可能不是最好的选择,因为它意味着所有具有ThreadParam的线程都将共享这个公共值。此外,每次新的ThreadParam更新时,他们都会看到它的变化。我希望这个声明至少是私有的final int c,以使它成为本地的、不可变的实例,从而实现线程安全。如果需要在外部发布c;创建一个公共int getC{return c;}就可以了。如果打算在运行中或从外部更改c,现在需要通过同步来保护它。@BobKuhar同意。它应该是私人的。但本规范仅供原作者参考。修复了它。这段代码在技术上是正确的,但是静态int c可能不是这里的最佳选择,因为它意味着所有具有ThreadParam的线程都将共享这个公共值。此外,每次新的ThreadParam更新时,他们都会看到它的变化。我希望这个声明至少是私有的final int c,以使它成为本地的、不可变的实例,从而实现线程安全。如果需要在外部发布c;创建一个公共int getC{return c;}就可以了。如果打算在运行中或从外部更改c,现在需要通过同步来保护它。@BobKuhar同意。它应该是私人的。但本规范仅供原作者参考。修好了。