我怎样才能传递一个参数到一个Java线程?
任何人都可以向我build议如何可以传递参数到一个线程?
另外,它是如何工作的匿名类?
您需要将构造函数中的parameter passing给线程对象:
public class MyThread implements Runnable { public MyThread(Object parameter) { // store parameter for later user } public void run() { } }
并调用它:
Runnable r = new MyThread(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)的类和一个你想传递的参数的构造函数。 然后,在创build新线程时,必须传入参数,然后启动线程,如下所示:
Thread t = new MyThread(args...); t.start();
Runnable是比BTW更好的解决scheme。 所以我宁愿:
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对象
通过一个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(); }
当你创build一个线程时,你需要一个Runnable
的实例。 传入参数的最简单方法是将其作为parameter passing给构造函数:
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");
当然,如果你想在参数改变的时候触发一个动作,你将不得不使用锁,这使得事情变得相当复杂。
要创build一个线程,您通常会创build您自己的Runnable实现。 将parameter passing给此类的构造函数中的线程。
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); } }
您可以扩展Thread
class
或Runnable
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();
或者编写一个实现了Runnable的类,并在适当定义的构造函数中传递任何需要的东西,或者编写一个扩展了Thread的类,该类使用合适的参数调用super()。
这个答案来得非常晚,但也许有人会觉得它有用。 这是关于如何将一个parameter passing给一个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
方法的签名(所以可能需要更多和/或不同的参数),当然甚至是它的名字,但是基本上你可以得到一个想法。
事实上,通过使用初始化块,还有另一种将parameter passing给匿名类的方法。 考虑这个:
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();
所以所有的都发生在初始化块内部。
你可以从Runnable派生一个类,并在构造(比如说)传入参数。
然后使用Thread.start(Runnable r)启动它;
如果你的意思是线程正在运行,那么只需在调用线程中持有对你的派生对象的引用,然后调用适当的setter方法(在适当的时候同步)
通过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); }
有一个简单的方法将parameter passing给runnables。 码:
public void Function(final type variable) { Runnable runnable = new Runnable() { public void run() { //Code adding here... } }; new Thread(runnable).start(); }
另一个select是 这种方法可以让你像使用asynchronous函数调用一样使用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 =新的线程(新的MyRunnable(参数)); t.start();
如果需要处理的结果,当子任务完成时,还需要协调完成MyRunnable。 你可以传回一个电话,或者等待线程't'等。
特别为Android
为了callback的目的,我通常使用input参数来实现我自己的genericsRunnable
:
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(); }
不,您不能将parameter passing给run()
方法。 签名告诉你(它没有参数)。 可能最简单的方法是使用一个在构造函数中使用参数并将其存储在最终variables中的专用对象:
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”的对象的数据完整性。 数据现在将存在于两个不同的线程中,因此您必须确保它是线程安全的。
从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();