Java 如何通过线程访问 Runnable 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2300579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access a Runnable object by Thread?
提问by Fluffy
Possible duplicate: need-help-returning-object-in-thread-run-method
可能重复:need-help-returning-object-in-thread-run-method
Hello. I have a class implementing runnable and I have a List, storing Threads instantiated with different objects of that class. How can I access properties of underlying objects given the thread object running them? Here is an example:
你好。我有一个实现 runnable 的类,我有一个 List,用于存储用该类的不同对象实例化的线程。给定运行它们的线程对象,如何访问底层对象的属性?下面是一个例子:
public class SO {
public static class TestRunnable implements Runnable {
public String foo = "hello";
public void run() {
foo = "world";
}
}
public static void main(String[] args) {
Thread t = new Thread(new TestRunnable());
t.start();
//How can I get the value of `foo` here?
}
}
采纳答案by Platinum Azure
I don't see any way to do it in the java.lang.Thread
docs.
我在java.lang.Thread
文档中看不到任何方法。
My best answer, then, is that you probably should be using List<Runnable>
instead of (or in addition to) List<Thread>
. Or perhaps you want some sort of mapstructure so that you can access the Runnable from the Thread. (For example, java.util.HashMap<java.lang.Thread, java.lang.Runnable>
)
那么,我最好的答案是,您可能应该使用List<Runnable>
而不是(或除了)List<Thread>
。或者您可能需要某种映射结构,以便您可以从线程访问 Runnable。(例如,java.util.HashMap<java.lang.Thread, java.lang.Runnable>
)
回答by Igor Artamonov
TestRunnable r = new TestRunnable();
Thread t = new Thread(r);
t.start();
//there you need to wait until thread is finished, or just a simple Thread.sleep(1000); at this case
System.out.println(r.foo);
BTW, in real case you need to use Callable
and FutureTask
顺便说一句,在实际情况下,您需要使用Callable
和FutureTask
回答by Stephen C
This is how you could implement this directly.
这就是您可以直接实现的方式。
public static void main(String[] args) {
// Keep a reference to the runnable object for later ...
TestRunnable r = new TestRunnable();
Thread t = new Thread(r);
t.start();
// Wait until the child thread has finished
t.join();
// Pull the result out of the runnable.
System.out.println(r.foo);
}
However, the modern (less error prone) way to do this kind of thing is to use the higher-level concurrency classes in java.util.concurrent
.
然而,做这种事情的现代(不太容易出错)的方法是使用java.util.concurrent
.
回答by Thilo
If you want to return the value of an asynchronous calculation, look at Callable and FutureTask:
如果要返回异步计算的值,看Callable和FutureTask:
FutureTask<String> task = new FutureTask(new Callable<String>() {
public String call() {
return "world";
}
});
new Thread(task).start();
String result = task.get();
回答by Peter Lawrey
The concurrency library supports this well. Note: If your task throws an Exception, the Future will hold this and throw a wrapping exception when you call get()
并发库很好地支持了这一点。注意:如果你的任务抛出一个异常,当你调用 get() 时,Future 将持有它并抛出一个包装异常
ExecutorService executor = Executors.newSingleThreadedExecutor();
Future<String> future = executor.submit(new Callable<String>() {
public String call() {
return "world";
}
});
String result = future.get();
回答by Chinasaur
I think in general you can/should avoid doing this, but if you really need to do it shouldn't something like MatrixFrog's suggestion work (untested):
我认为总的来说你可以/应该避免这样做,但如果你真的需要这样做,它不应该像 MatrixFrog 的建议工作(未经测试):
class RunnableReferencingThread extends Thread {
public final Runnable runnable;
public RunnableReferencingThread(Runnable r) {
super(r);
this.runnable = r;
}
}
?
?
回答by Paul Crowley
You could subclass Thread, and add the method you need. You'll have to keep your own copy of the target Runnable and override all the Thread constructors you use to create the Thread, because of some annoying implementation details of Thread.
您可以继承 Thread,并添加您需要的方法。由于 Thread 的一些烦人的实现细节,您必须保留自己的目标 Runnable 副本并覆盖用于创建 Thread 的所有 Thread 构造函数。
回答by user1870213
I had the same problem. Here is my solution:
我有同样的问题。这是我的解决方案:
public static class TestRunnable implements Runnable {
public String foo = "hello";
public void run() {
foo = "world";
}
public static void main(String[] args) {
TestRunnable runobject = new TestRunnable();
Thread t = new Thread(runobject);
runobject.foo; //The variable from runnable. hello;
t.start();
runobject.foo; //The variable from runnable. world;
}
回答by gerardw
If your thread has state information, forget Runnable and simply extend Thread, overriding the run method.
如果您的线程有状态信息,请忘记 Runnable 并简单地扩展 Thread,覆盖 run 方法。
回答by Janus Varmarken
To give a concrete example of Paul Crowley's solution, I think this is what he suggests:
举一个 Paul Crowley 解决方案的具体例子,我认为这就是他的建议:
public class BackgroundJob<JOB extends Runnable> extends Thread {
private final JOB mJob;
public BackgroundJob(JOB job) {
super(job);
mJob = job;
}
public JOB getJob() {
return mJob;
}
}