谁能建议我如何将参数传递给线程?
另外,它如何用于匿名类?
Consumer<T>。
                谁能建议我如何将参数传递给线程?
另外,它如何用于匿名类?
Consumer<T>。
                Answers:
您需要将构造函数中的参数传递给Runnable对象:
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();
r将具有相同的参数,因此,如果我们要将不同的参数传递给正在运行的多个线程,则需要为每个线程使用所需的参数MyThread创建一个新MyThread实例。换句话说,要启动和运行线程,我们需要创建两个对象:Thread和MyThread。从性能角度来看,这被认为是不好的吗?
                    在回应问题编辑时,这是匿名类的工作方式
   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();
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();
这个答案与这个类似的问题基本相同:如何将参数传递给Thread对象
parameter直接从run()方法访问而p根本不使用任何字段。似乎有效。是否有一些我没有事先复制parameter到的微妙的多线程东西p?
                    )在第一个例子
                    final X parameter在new Runnable()生产线前有,我就可以进入parameter内部run()。我不需要做额外的事情p = parameter。
                    final不再那么重要了;变量有效地为最终变量就足够了(尽管使用它没有害处)
                    通过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();
}
@Override?
                    @Override明确声明它正在覆盖Thread类中的抽象方法。
                    这个答案来得很晚,但是也许有人会觉得有用。它是关于如何在Runnable不声明命名类的情况下将参数传递给的(对于内联函数很方便):
String someValue = "Just a demo, really...";
new Thread(new Runnable() {
    private String myParam;
    public Runnable init(String myParam) {
        this.myParam = myParam;
        return this;
    }
    @Override
    public void run() {
        System.out.println("This is called from another thread.");
        System.out.println(this.myParam);
    }
}.init(someValue)).start();
当然,您可以将执行推迟start到更方便或更合适的时间。而且由您决定init方法的签名(因此它可能需要更多和/或不同的参数),当然还有它的名称,但这基本上是您的主意。
实际上,还有另一种使用初始化程序块将参数传递给匿名类的方法。考虑一下:
String someValue = "Another demo, no serious thing...";
int anotherValue = 42;
new Thread(new Runnable() {
    private String myParam;
    private int myOtherParam;
    {
        this.myParam = someValue;
        this.myOtherParam = anotherValue;
    }
    @Override
    public void run() {
        System.out.println("This comes from another thread.");
        System.out.println(this.myParam + ", " + this.myOtherParam);
    }
}).start();
因此,所有操作都发生在初始化程序块内部。
this.myParam那真的必要吗?您不能只删除私有变量并从外部范围引用该变量吗?我理解(当然),这有一些含义,例如,在启动线程后可以更改变量。
                    创建线程时,您需要一个实例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;
}
一旦有了它,就可以通过如下调用来更改参数的值:
myRunnable.setMyParam("Goodbye World");当然,如果要在更改参数时触发操作,则必须使用锁,这会使事情变得更加复杂。
您可以扩展或并根据需要提供参数。在docs中有简单的示例。我将它们移植到这里:Thread classRunnable class
 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();在Java 8中,您可以将lambda表达式与Concurrency API配合使用,并ExecutorService作为高级替换直接使用线程:
newCachedThreadPool()创建一个线程池,该线程池根据需要创建新线程,但是将在先前构造的线程可用时重用它们。这些池通常将提高执行许多短期异步任务的程序的性能。
    private static final ExecutorService executor = Executors.newCachedThreadPool();
    executor.submit(() -> {
        myFunction(myParam1, myParam2);
    });另请参见executors javadocs。
通过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);
}不,您不能将参数传递给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();一旦这样做-您必须注意传递给'WorkingTask'的对象的数据完整性。数据现在将存在于两个不同的线程中,因此您必须确保它是线程安全的。
另一种选择;这种方法使您可以像异步函数调用一样使用Runnable项。如果您的任务不需要返回结果,例如,它仅执行某些操作,则无需担心如何传递“结果”。
这种模式使您可以重用需要某种内部状态的项目。当在构造函数中不传递参数时,需要注意调解程序对参数的访问。如果用例涉及不同的调用者,则可能需要更多检查。
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 = new Thread(new MyRunnable(parameter)); t.start();
如果需要处理结果,则还需要在子任务完成时协调MyRunnable的完成。您可以回拨电话,也可以等待线程“ t”等。
为了回调,我通常Runnable使用输入参数实现自己的泛型:
public interface Runnable<TResult> {
    void run(TResult result);
}用法很简单:
myManager.doCallbackOperation(new Runnable<MyResult>() {
    @Override
    public void run(MyResult result) {
        // do something with the result
    }
});在经理中:
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();
}创建你的类,一个局部变量extends Thread或implements Runnable。
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"