如何将参数传递给 Java 线程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/877096/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:32:50  来源:igfitidea点击:

How can I pass a parameter to a Java Thread?

javamultithreading

提问by Steve

Can anyone suggest to me how I can pass a parameter to a thread?

谁能建议我如何将参数传递给线程?

Also, how does it work for anonymous classes?

另外,它如何用于匿名类?

采纳答案by Alnitak

You need to pass the parameter in the constructor to the Runnable object:

您需要将构造函数中的参数传递给 Runnable 对象:

public class MyRunnable implements Runnable {

   public MyRunnable(Object parameter) {
       // store parameter for later user
   }

   public void run() {
   }
}

and invoke it thus:

并这样调用它:

Runnable r = new MyRunnable(param_value);
new Thread(r).start();

回答by dfa

via constructor of a Runnable or Thread class

通过 Runnable 或 Thread 类的构造函数

class MyThread extends Thread {

    private String to;

    public MyThread(String to) {
        this.to = to;
    }

    @Override
    public void run() {
        System.out.println("hello " + to);
    }
}

public static void main(String[] args) {
    new MyThread("world!").start();
}

回答by PaulJWilliams

Either write a class that implements Runnable, and pass whatever you need in a suitably defined constructor, or write a class that extends Thread with a suitably defined constructor that calls super() with appropriate parameters.

要么编写一个实现 Runnable 的类,并在适当定义的构造函数中传递您需要的任何内容,要么编写一个扩展 Thread 的类,该类使用适当定义的构造函数调用 super() 并使用适当的参数。

回答by Brian Agnew

You can derive a class from Runnable, and during the construction (say) pass the parameter in.

您可以从 Runnable 派生一个类,并在构造期间(例如)传入参数。

Then launch it using Thread.start(Runnable r);

然后使用 Thread.start(Runnable r); 启动它。

If you mean whilstthe thread is running, then simply hold a reference to your derived object in the calling thread, and call the appropriate setter methods (synchronising where appropriate)

如果您的意思是线程运行时,那么只需在调用线程中保留对派生对象的引用,并调用适当的 setter 方法(在适当的地方同步)

回答by Nick Fortescue

For Anonymous classes:

对于匿名类:

In response to question edits here is how it works for Anonymous classes

为了回答问题,这里的编辑是匿名类的工作原理

   final X parameter = ...; // the final is important
   Thread t = new Thread(new Runnable() {
       p = parameter;
       public void run() { 
         ...
       };
   t.start();


Named classes:

命名类:

You have a class that extends Thread (or implements Runnable) and a constructor with the parameters you'd like to pass. Then, when you create the new thread, you have to pass in the arguments, and then start the thread, something like this:

您有一个扩展 Thread(或实现 Runnable)的类和一个带有您想要传递的参数的构造函数。然后,当您创建新线程时,您必须传入参数,然后启动线程,如下所示:

Thread t = new MyThread(args...);
t.start();

Runnable is a much better solution than Thread BTW. So I'd prefer:

Runnable 是比 Thread BTW 更好的解决方案。所以我更喜欢:

   public class MyRunnable implements Runnable {
      private X parameter;
      public MyRunnable(X parameter) {
         this.parameter = parameter;
      }

      public void run() {
      }
   }
   Thread t = new Thread(new MyRunnable(parameter));
   t.start();

This answer is basically the same as this similar question: How to pass parameters to a Thread object

这个答案与这个类似的问题基本相同:How to pass parameters to a Thread object

回答by Mnementh

To create a thread you normally create your own implementation of Runnable. Pass the parameters to the thread in the constructor of this class.

要创建线程,您通常会创建自己的 Runnable 实现。在该类的构造函数中将参数传递给线程。

class MyThread implements Runnable{
   private int a;
   private String b;
   private double c;

   public MyThread(int a, String b, double c){
      this.a = a;
      this.b = b;
      this.c = c;
   }

   public void run(){
      doSomething(a, b, c);
   }
}

回答by jwoolard

When you create a thread, you need an instance of Runnable. The easiest way to pass in a parameter would be to pass it in as an argument to the constructor:

创建线程时,需要一个Runnable. 传递参数的最简单方法是将其作为参数传递给构造函数:

public class MyRunnable implements Runnable {

    private volatile String myParam;

    public MyRunnable(String myParam){
        this.myParam = myParam;
        ...
    }

    public void run(){
        // do something with myParam here
        ...
    }

}

MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();

If you then want to change the parameter while the thread is running, you can simply add a setter method to your runnable class:

如果您想在线程运行时更改参数,只需向可运行类添加一个 setter 方法:

public void setMyParam(String value){
    this.myParam = value;
}

Once you have this, you can change the value of the parameter by calling like this:

一旦你有了这个,你可以通过像这样调用来更改参数的值:

myRunnable.setMyParam("Goodbye World");

Of course, if you want to trigger an action when the parameter is changed, you will have to use locks, which makes things considerably more complex.

当然,如果你想在参数改变时触发一个动作,你将不得不使用锁,这会使事情变得更加复杂。

回答by bruno conde

You can either extend the Threadclassor the Runnableclassand provide parameters as you want. There are simple examples in the docs. I'll port them here:

您可以根据需要扩展或并提供参数。文档中有简单的例子。我将把它们移植到这里:ThreadclassRunnableclass

 class PrimeThread extends Thread {
     long minPrime;
     PrimeThread(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }

 PrimeThread p = new PrimeThread(143);
 p.start();

 class PrimeRun implements Runnable {
     long minPrime;
     PrimeRun(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }


 PrimeRun p = new PrimeRun(143);
 new Thread(p).start();

回答by Java42

Parameter passing via the start() and run() methods:

通过 start() 和 run() 方法传递参数:

// Tester
public static void main(String... args) throws Exception {
    ThreadType2 t = new ThreadType2(new RunnableType2(){
        public void run(Object object) {
            System.out.println("Parameter="+object);
        }});
    t.start("the parameter");
}

// New class 1 of 2
public class ThreadType2 {
    final private Thread thread;
    private Object objectIn = null;
    ThreadType2(final RunnableType2 runnableType2) {
        thread = new Thread(new Runnable() {
            public void run() {
                runnableType2.run(objectIn);
            }});
    }
    public void start(final Object object) {
        this.objectIn = object;
        thread.start();
    }
    // If you want to do things like setDaemon(true); 
    public Thread getThread() {
        return thread;
    }
}

// New class 2 of 2
public interface RunnableType2 {
    public void run(Object object);
}

回答by will

One further option; this approach lets you use the Runnable item like an asynchronous function call. If your task does not need to return a result, e.g. it just performs some action you don't need to worry about how you pass back an "outcome".

另一种选择;这种方法让您可以像异步函数调用一样使用 Runnable 项。如果您的任务不需要返回结果,例如它只是执行某些操作,您就不必担心如何传回“结果”。

This pattern lets you reuse an item, where you need some kind of internal state. When not passing parameter(s) in the constructor care is needed to mediate the programs access to parameters. You may need more checks if your use-case involves different callers, etc.

此模式允许您重用需要某种内部状态的项目。当不在构造函数中传递参数时,需要注意调解程序对参数的访问。如果您的用例涉及不同的调用者等,您可能需要更多检查。

public class MyRunnable implements Runnable 
{
  private final Boolean PARAMETER_LOCK  = false;
  private X parameter;

  public MyRunnable(X parameter) {
     this.parameter = parameter;
  }

  public void setParameter( final X newParameter ){

      boolean done = false;
      synchronize( PARAMETER_LOCK )
      {
          if( null == parameter )
          {
              parameter = newParameter;
              done = true;
          }
      }
      if( ! done )
      {
          throw new RuntimeException("MyRunnable - Parameter not cleared." );
      }
  }


  public void clearParameter(){

      synchronize( PARAMETER_LOCK )
      {
          parameter = null;
      }
  }


  public void run() {

      X localParameter;

      synchronize( PARAMETER_LOCK )
      {
          localParameter = parameter;
      }

      if( null != localParameter )
      {
         clearParameter();   //-- could clear now, or later, or not at all ...
         doSomeStuff( localParameter );
      }

  }

}

}

Thread t = new Thread(new MyRunnable(parameter)); t.start();

线程 t = new Thread(new MyRunnable(parameter)); t.start();

If you need a result of processing, you will also need to coordinate completion of MyRunnable when the sub-task finishes. You could pass a call back or just wait on the Thread 't', etc.

如果需要处理结果,还需要在子任务完成时协调完成MyRunnable。您可以通过回调或只是等待线程 't' 等。