有人能告诉我如何将参数传递给线程吗?
另外,匿名类是如何工作的?
有人能告诉我如何将参数传递给线程吗?
另外,匿名类是如何工作的?
当前回答
不,你不能将参数传递给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”的对象的数据完整性。数据现在将存在于两个不同的线程中,因此您必须确保它是线程安全的。
其他回答
首先,我想指出其他答案都是正确的。 但是,在构造函数中使用形参可能对所有人来说都不是最好的主意。
在很多情况下,你会想要使用“匿名内部类”,并重写run()方法,因为为每个用途定义特定的类是很痛苦的。 (新MyRunnable(){…})
在创建Runnable时,参数可能无法在构造函数中传递。例如,如果你将这个对象传递给一个方法,这个方法将在单独的线程中执行一些工作,然后调用你的runnable,将该工作的结果应用到它。
在这种情况下,使用如下方法: public MyRunnable withParameter(对象参数),可能是更有用的选择。
我并不是说这是解决问题的最好办法,但它可以解决问题。
对于匿名类:
在这里回答问题编辑是如何工作的匿名类
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更好的解决方案。所以我更喜欢:
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对象
在Java 8中,你可以在并发API和ExecutorService中使用lambda表达式,作为直接使用线程的高级替代:
创建一个用于创建新线程的线程池 根据需要,但将重用之前构造的线程 可用。这些池通常会提高执行许多短期异步任务的程序的性能。
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
参见executors javadocs。
通过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();
}
Android专用
为了回调的目的,我通常使用输入参数实现自己的泛型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();
}