多线程 - 如何将参数传递给Java线程?
谁能告诉我如何将参数传递给线程?
此外,它如何为匿名类工作?
Steve asked 2019-02-25T07:34:06Z
17个解决方案
323 votes
您需要将构造函数中的参数传递给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();
Alnitak answered 2019-02-25T07:34:29Z
100 votes
对于匿名类:
回答问题编辑,这里是匿名类的工作原理
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对象
Nick Fortescue answered 2019-02-25T07:35:32Z
36 votes
通过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();
}
dfa answered 2019-02-25T07:35:56Z
16 votes
创建线程时,需要一个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方法添加到runnable类:
public void setMyParam(String value){
this.myParam = value;
}
一旦你有了这个,你可以通过这样调用来改变参数的值:
myRunnable.setMyParam("Goodbye World");
当然,如果要在参数更改时触发操作,则必须使用锁定,这会使事情变得更加复杂。
jwoolard answered 2019-02-25T07:36:44Z
14 votes
这个答案来得很晚,但也许有人会发现它很有用。 它是关于如何将参数传递给start,甚至没有声明命名类(内联器方便):
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();
所有这些都发生在初始化程序块内部。
Cromax answered 2019-02-25T07:37:34Z
9 votes
要创建一个线程,通常可以创建自己的Runnable实现。 将参数传递给此类的构造函数中的线程。
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);
}
}
Mnementh answered 2019-02-25T07:38:01Z
8 votes
您可以延长Runnable Runnable或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();
bruno conde answered 2019-02-25T07:38:30Z
7 votes
编写一个实现Runnable的类,并在适当定义的构造函数中传递您需要的任何内容,或编写一个使用适当定义的构造函数扩展Thread的类,该构造函数使用适当的参数调用super()。
PaulJWilliams answered 2019-02-25T07:38:56Z
4 votes
从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();
Jeff G answered 2019-02-25T07:39:23Z
3 votes
您可以从Runnable派生一个类,并在构造期间(比如)传入参数。
然后使用Thread.start(Runnable r)启动它;
如果你的意思是在线程运行时,那么只需在调用线程中保存对派生对象的引用,并调用适当的setter方法(在适当的地方同步)
Brian Agnew answered 2019-02-25T07:40:03Z
3 votes
通过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);
}
Java42 answered 2019-02-25T07:40:29Z
2 votes
有一种将参数传递给runnables的简单方法。码:
public void Function(final type variable) {
Runnable runnable = new Runnable() {
public void run() {
//Code adding here...
}
};
new Thread(runnable).start();
}
Chromium answered 2019-02-25T07:40:54Z
2 votes
在Java 8中,您可以将executors表达式与Concurrency API& ExecutorService作为直接使用线程的更高级别替代:
executors创建一个创建新线程的线程池 根据需要,但会重用以前构造的线程 可用。 这些池通常会提高执行许多短期异步任务的程序的性能。
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
另见executors javadocs。
Stuart Cardall answered 2019-02-25T07:41:35Z
1 votes
另一个选择; 这种方法允许您像使用异步函数调用一样使用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'等。
will answered 2019-02-25T07:42:28Z
1 votes
特别适用于Android
出于回调目的,我通常使用输入参数实现我自己的通用Runnable:
public interface Runnable {
void run(TResult result);
}
用法很简单:
myManager.doCallbackOperation(new Runnable() {
@Override
public void run(MyResult result) {
// do something with the result
}
});
经理:
public void doCallbackOperation(Runnable runnable) {
new AsyncTask() {
@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();
}
Andrei answered 2019-02-25T07:43:13Z
1 votes
不,你不能将参数传递给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'的对象的数据完整性。 现在数据将存在于两个不同的线程中,因此您必须确保它是线程安全的。
Mihir Patel answered 2019-02-25T07:43:47Z
0 votes
在类中创建一个局部变量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"
calthecoder answered 2019-02-25T07:44:24Z