Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将参数传递给Java线程?_Java_Multithreading - Fatal编程技术网

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

如何将参数传递给Java线程?,java,multithreading,Java,Multithreading,有人能建议我如何将参数传递给线程吗 另外,它如何适用于匿名类?通过可运行类或线程类的构造函数 class MyThread extends Thread { private String to; public MyThread(String to) { this.to = to; } @Override public void run() { System.out.println("hello " + to);

有人能建议我如何将参数传递给线程吗


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

通过可运行类或线程类的构造函数

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

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

您可以从Runnable派生一个类,并在构造过程中(比如)传入参数

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


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

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

public class MyRunnable implements Runnable {

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

   public void run() {
   }
}
并据此援引:

Runnable r = new MyRunnable(param_value);
new Thread(r).start();
对于匿名类: 作为对问题的回答,这里是它如何为匿名类工作的

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

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

Thread t = new MyThread(args...);
t.start();
myRunnable.setMyParam("Goodbye World");
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();

这个答案与这个类似的问题基本相同:

要创建线程,您通常会创建自己的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);
   }
}

创建线程时,需要
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();
如果随后希望在线程运行时更改参数,只需向可运行类添加setter方法:

public void setMyParam(String value){
    this.myParam = value;
}
完成此操作后,可以通过如下方式调用来更改参数的值:

Thread t = new MyThread(args...);
t.start();
myRunnable.setMyParam("Goodbye World");
当然,如果要在参数更改时触发操作,则必须使用锁,这会使事情变得更加复杂。

您可以扩展
类或
类,并根据需要提供参数。下面是一些简单的例子。我将把它们移植到这里:

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

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


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

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

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

  }
}

线程t=新线程(新MyRunnable(参数)); t、 start()

如果需要处理结果,还需要在子任务完成时协调MyRunnable的完成。你可以回电话,或者只是等待线程“t”等等。

Android专用 出于回调目的,我通常使用输入参数实现自己的通用
Runnable

公共接口可运行{
无效运行(TResult结果);
}
用法很简单:

myManager.doCallbackOperation(new Runnable<MyResult>() {
    @Override
    public void run(MyResult result) {
        // do something with the result
    }
});
myManager.doCallbackOperation(新的Runnable(){
@凌驾
公共作废运行(MyResult){
//对结果做点什么
}
});
在经理中:

public void doCallbackOperation(Runnable<MyResult> runnable) {
    new AsyncTask<Void, Void, MyResult>() {
        @Override
        protected MyResult doInBackground(Void... params) {
            // do background operation
            return new MyResult(); // return resulting object
        }

        @Override
        protected void onPostExecute(MyResult result) {
            // execute runnable passing the result when operation has finished
            runnable.run(result);
        }
    }.execute();
}
public void doCallbackOperation(可运行可运行){
新建异步任务(){
@凌驾
受保护的MyResult doInBackground(无效…参数){
//做后台操作
返回新的MyResult();//返回结果对象
}
@凌驾
受保护的void onPostExecute(MyResult结果){
//执行runnable,在操作完成时传递结果
runnable.run(结果);
}
}.execute();
}

有一种将参数传递到可运行文件的简单方法。 代码:


不,您不能将参数传递给
run()
方法。签名告诉您(它没有参数)。可能最简单的方法是使用专门构建的对象,该对象在构造函数中接受一个参数并将其存储在最终变量中:

public class WorkingTask implements Runnable
{
    private final Object toWorkWith;

    public WorkingTask(Object workOnMe)
    {
        toWorkWith = workOnMe;
    }

    public void run()
    {
        //do work
    }
}

//...
Thread t = new Thread(new WorkingTask(theData));
t.start();

一旦你这样做了,你必须小心你传递到“工作任务”的对象的数据完整性。数据现在将存在于两个不同的线程中,因此您必须确保它是线程安全的。

这个答案来得很晚,但可能有人会发现它很有用。这是关于如何将参数传递给
可运行的
,而无需声明命名类(对于内联程序来说很方便):

String someValue=“只是一个演示,真的……”;
新线程(newrunnable()){
私有字符串myParam;
公共可运行init(字符串myParam){
this.myParam=myParam;
归还这个;
}
@凌驾
公开募捐{
System.out.println(“这是从另一个线程调用的”);
System.out.println(this.myParam);
}
}.init(someValue)).start();
当然,您可以将
start
的执行推迟到更方便或合适的时间。
init
方法的签名是什么取决于您(因此它可能需要更多和/或不同的参数),当然还有它的名称,但基本上您已经知道了

事实上,还有另一种向匿名类传递参数的方法,即使用初始值设定项块。考虑这一点:

String someValue=“另一个演示,没什么大不了的……”;
int-anotherValue=42;
新线程(newrunnable()){
私有字符串myParam;
私人智能手机;
//实例初始值设定项
{
this.myParam=someValue;
public class WorkingTask implements Runnable
{
    private final Object toWorkWith;

    public WorkingTask(Object workOnMe)
    {
        toWorkWith = workOnMe;
    }

    public void run()
    {
        //do work
    }
}

//...
Thread t = new Thread(new WorkingTask(theData));
t.start();
final String param1 = "First param";
final int param2 = 2;
new Thread(() -> {
    // Do whatever you want here: param1 and param2 are in-scope!
    System.out.println(param1);
    System.out.println(param2);
}).start();
    private static final ExecutorService executor = Executors.newCachedThreadPool();

    executor.submit(() -> {
        myFunction(myParam1, myParam2);
    });
public class Extractor extends Thread {
    public String webpage = "";
    public Extractor(String w){
        webpage = w;
    }
    public void setWebpage(String l){
        webpage = l;
    }

    @Override
    public void run() {// l is link
        System.out.println(webpage);
    }
    public String toString(){
        return "Page: "+webpage;
    }}
Extractor e = new Extractor("www.google.com");
e.start();
"www.google.com"
int x = 0;
new Thread((new Runnable() {
     int x;
     public void run() {
        // stuff with x and whatever else you want
     }
     public Runnable pass(int x) {
           this.x = x;
           return this;
     }
}).pass(x)).start();