有人能告诉我如何将参数传递给线程吗?

另外,匿名类是如何工作的?


当前回答

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

其他回答

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

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”的对象的数据完整性。数据现在将存在于两个不同的线程中,因此您必须确保它是线程安全的。

参数通过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()方法,因为为每个用途定义特定的类是很痛苦的。 (新MyRunnable(){…})

在创建Runnable时,参数可能无法在构造函数中传递。例如,如果你将这个对象传递给一个方法,这个方法将在单独的线程中执行一些工作,然后调用你的runnable,将该工作的结果应用到它。

在这种情况下,使用如下方法: public MyRunnable withParameter(对象参数),可能是更有用的选择。

我并不是说这是解决问题的最好办法,但它可以解决问题。

你需要在构造函数中将参数传递给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();

在Java 8中,你可以在并发API和ExecutorService中使用lambda表达式,作为直接使用线程的高级替代:

创建一个用于创建新线程的线程池 根据需要,但将重用之前构造的线程 可用。这些池通常会提高执行许多短期异步任务的程序的性能。

    private static final ExecutorService executor = Executors.newCachedThreadPool();

    executor.submit(() -> {
        myFunction(myParam1, myParam2);
    });

参见executors javadocs。