如何将参数传递给Java线程?
有人能建议我如何将参数传递给线程吗如何将参数传递给Java线程?,java,multithreading,Java,Multithreading,有人能建议我如何将参数传递给线程吗 另外,它如何适用于匿名类?通过可运行类或线程类的构造函数 class MyThread extends Thread { private String to; public MyThread(String to) { this.to = to; } @Override public void run() { System.out.println("hello " + to);
另外,它如何适用于匿名类?通过可运行类或线程类的构造函数
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();
}
要么编写一个实现Runnable的类,并在适当定义的构造函数中传递所需的任何内容,要么编写一个使用适当定义的构造函数扩展线程的类,该构造函数使用适当的参数调用super()。您可以从Runnable派生一个类,并在构造过程中(比如)传入参数 然后使用Thread.start(Runnable r)启动它
如果您的意思是在线程运行时,只需在调用线程中保留对派生对象的引用,并调用适当的setter方法(在适当的情况下进行同步)您需要将构造函数中的参数传递给可运行对象:
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();
myRunnable.setMyParam("Goodbye World");
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();
这个答案与这个类似的问题基本相同:要创建线程,您通常会创建自己的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);
}
}
创建线程时,需要
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;
}
完成此操作后,可以通过如下方式调用来更改参数的值:
Thread t = new MyThread(args...);
t.start();
myRunnable.setMyParam("Goodbye World");
当然,如果要在参数更改时触发操作,则必须使用锁,这会使事情变得更加复杂。您可以扩展类或类,并根据需要提供参数。下面是一些简单的例子。我将把它们移植到这里:
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();
通过start()和run()方法传递的参数:
另一种选择;这种方法允许您像异步函数调用一样使用可运行项。如果您的任务不需要返回结果,例如,它只执行一些操作,您不需要担心如何返回“结果”
此模式允许重用需要某种内部状态的项。当不在构造函数中传递参数时,需要注意调解程序对参数的访问。如果您的用例涉及不同的调用者等,您可能需要更多的检查
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专用
出于回调目的,我通常使用输入参数实现自己的通用Runnable
:
公共接口可运行{
无效运行(TResult结果);
}
用法很简单:
myManager.doCallbackOperation(new Runnable<MyResult>() {
@Override
public void run(MyResult result) {
// do something with the result
}
});
myManager.doCallbackOperation(新的Runnable(){
@凌驾
公共作废运行(MyResult){
//对结果做点什么
}
});
在经理中:
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();
}
public void doCallbackOperation(可运行可运行){
新建异步任务(){
@凌驾
受保护的MyResult doInBackground(无效…参数){
//做后台操作
返回新的MyResult();//返回结果对象
}
@凌驾
受保护的void onPostExecute(MyResult结果){
//执行runnable,在操作完成时传递结果
runnable.run(结果);
}
}.execute();
}
有一种将参数传递到可运行文件的简单方法。
代码:
不,您不能将参数传递给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();
一旦你这样做了,你必须小心你传递到“工作任务”的对象的数据完整性。数据现在将存在于两个不同的线程中,因此您必须确保它是线程安全的。这个答案来得很晚,但可能有人会发现它很有用。这是关于如何将参数传递给可运行的
,而无需声明命名类(对于内联程序来说很方便):
String someValue=“只是一个演示,真的……”;
新线程(newrunnable()){
私有字符串myParam;
公共可运行init(字符串myParam){
this.myParam=myParam;
归还这个;
}
@凌驾
公开募捐{
System.out.println(“这是从另一个线程调用的”);
System.out.println(this.myParam);
}
}.init(someValue)).start();
当然,您可以将start
的执行推迟到更方便或合适的时间。init
方法的签名是什么取决于您(因此它可能需要更多和/或不同的参数),当然还有它的名称,但基本上您已经知道了
事实上,还有另一种向匿名类传递参数的方法,即使用初始值设定项块。考虑这一点:
String someValue=“另一个演示,没什么大不了的……”;
int-anotherValue=42;
新线程(newrunnable()){
私有字符串myParam;
私人智能手机;
//实例初始值设定项
{
this.myParam=someValue;
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();
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();
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
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"
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();