有人可以向我建议如何将参数传递给线程吗?
对于匿名类,它是如何工作的呢?
从Java 8开始,您可以使用lambda捕获有效终态的参数。例如:
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();
通过 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()
方法传递参数。方法签名告诉你这一点(它没有参数)。可能最简单的方法是使用一个专门构建的对象,在构造函数中接受参数并将其存储在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”的对象的数据完整性。数据现在存在于两个不同的线程中,因此您必须确保它是线程安全的。
有一种简单的方式可以将参数传递给可运行对象。 代码:
public void Function(final type variable) {
Runnable runnable = new Runnable() {
public void run() {
//Code adding here...
}
};
new Thread(runnable).start();
}
还有一种选择:这种方法让你像异步函数调用一样使用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”等。
扩展Thread
或实现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"
为了回调目的,我通常会实现自己的通用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();
}
首先,我想指出其他答案是正确的。然而,对于你们所有人来说,在构造函数中使用参数可能不是最好的选择。
在许多情况下,您将希望使用“匿名内部类”,并覆盖run()
方法,因为为每个用途定义特定的类很繁琐。(new MyRunnable(){...}
)
而且,在创建该Runnable时,可能无法将参数传递给构造函数。例如,如果您将此对象传递给一个方法,该方法将在单独的线程中执行一些工作,然后调用您的可运行对象,并将该工作的结果应用于它。
在这种情况下,使用像这样的方法:public MyRunnable withParameter(Object parameter)
,可能会成为更有用的选择。
我不认为这是解决问题的最佳方案,但它可以完成工作。
Consumer<T>
。 - Alex78191