有人可以向我建议如何将参数传递给线程吗?
对于匿名类,它是如何工作的呢?
你需要在构造函数中传递参数给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();
针对问题的编辑,以下是匿名类的工作原理:
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();
顺便说一下,与Thread相比,Runnable是一个更好的解决方案。所以我更喜欢:
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();
这个答案与这个类似的问题基本相同:如何向线程对象传递参数
run()
方法中访问parameter
而不使用像p
这样的字段。它似乎可以工作。如果我在此之前没有将parameter
复制到p
中,是否会错过一些微妙的多线程问题? - Randall Cook)
。 - Hack-Rnew Runnable()
行之前有final X参数
,那么我就可以在run()
内部访问parameter
。我不需要额外做p = parameter
。 - wisbuckyfinal
不再那么重要了;如果变量是有效的 final(尽管没有它也没有关系),那就足够了。 - user85421通过一个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();
}
@Override
呢? - Snow@Override
明确表示它正在覆盖 Thread 类中的抽象方法。 - wyskoj这个答案来得非常晚,但也许有人会发现它有用。它是关于如何在不声明命名类的情况下将参数传递给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
方法的签名是由您决定的(因此它可能需要更多和/或不同的参数),甚至名称也可以改变,但基本上您已经有了一个想法。
实际上,还有另一种通过初始化块将参数传递给匿名类的方式。请考虑以下内容:
String someValue = "Another demo, no serious thing...";
int anotherValue = 42;
new Thread(new Runnable() {
private String myParam;
private int myOtherParam;
// instance initializer
{
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();
所以所有的操作都发生在初始化块内部。this.myParam
真的必要吗?你不能只丢掉私有变量并从外部作用域引用变量吗?当然,我理解这会带来一些影响,比如在启动线程后变量可能会被更改。 - oligofren创建线程时,需要一个 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方法:
public void setMyParam(String value){
this.myParam = value;
}
有了这个,你可以通过如下方式调用来更改参数的值:
myRunnable.setMyParam("Goodbye World");
当然,如果你想在参数改变时触发某个操作,你将需要使用锁定(locks),这会使得事情变得更加复杂。
我知道我有点晚了,但我遇到了这个问题并采取了一种非正统的方式。我想不用创建一个新类来解决它,所以我想出了这个方法:
int x = 0;
new Thread((new Runnable() {
int x;
public void run() {
// stuff with x and whatever else you want
}
public Runnable pass(int x) {
this.x = x;
return this;
}
}).pass(x)).start();
Thread
类或Runnable
类并根据需要提供参数。在文档中有简单的示例。我将把它们放在这里: 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实现。在这个类的构造函数中传递参数给线程。
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);
}
}
lambda
表达式与并发API和ExecutorService
以更高级别的方式替代直接使用线程:
newCachedThreadPool()
创建一个线程池,根据需要创建新线程,但在可用时将重用先前构造的线程。这些池通常会提高执行许多短期异步任务的程序的性能。
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
另请参见 executors
Java文档。
Consumer<T>
。 - Alex78191