可能重复:need-help-returning-object-in-thread-run-method
您好。我有一个实现runnable的类,我有一个List,存储用该类的不同对象实例化的Threads。在线程对象运行它们的情况下,如何访问底层对象的属性?这是一个例子:
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?
}
}
答案 0 :(得分:12)
我在java.lang.Thread
文档中看不到任何方法。
我最好的答案是,你可能应该使用List<Runnable>
而不是(或除了)List<Thread>
。或者您可能需要某种map结构,以便可以从线程访问Runnable。 (例如,java.util.HashMap<java.lang.Thread, java.lang.Runnable>
)
答案 1 :(得分:10)
并发库很好地支持了这一点。注意:如果您的任务抛出异常,则在调用get()
时,Future将保留此并抛出包装异常ExecutorService executor = Executors.newSingleThreadedExecutor();
Future<String> future = executor.submit(new Callable<String>() {
public String call() {
return "world";
}
});
String result = future.get();
答案 2 :(得分:4)
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,在实际情况下,您需要使用Callable
和FutureTask
答案 3 :(得分:4)
如果要返回异步计算的值,请查看Callable和FutureTask:
FutureTask<String> task = new FutureTask(new Callable<String>() {
public String call() {
return "world";
}
});
new Thread(task).start();
String result = task.get();
答案 4 :(得分:2)
我认为一般来说你可以/应该避免这样做,但是如果你真的需要这样做,那就不应该像MatrixFrog的建议那样(未经测试):
class RunnableReferencingThread extends Thread {
public final Runnable runnable;
public RunnableReferencingThread(Runnable r) {
super(r);
this.runnable = r;
}
}
答案 5 :(得分:2)
如果您的线程有状态信息,请忘记Runnable并简单地扩展Thread,覆盖run方法。
答案 6 :(得分:1)
这是你可以直接实现的方法。
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);
}
但是,现代(不易出错)的方法是使用java.util.concurrent
中的更高级别的并发类。
答案 7 :(得分:1)
我遇到了同样的问题。这是我的解决方案:
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;
}
答案 8 :(得分:1)
为了给出保罗克劳利解决方案的一个具体例子,我认为这是他的建议:
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;
}
}
答案 9 :(得分:0)
您可以继承Thread,并添加您需要的方法。您必须保留自己的目标Runnable副本并覆盖用于创建Thread的所有Thread构造函数,因为Thread的一些烦人的实现细节。
答案 10 :(得分:0)
我认为,如果可以的话,就是要恢复这种状况。那么在这种情况下,一个好的解决方案是将线程存储在runnable类中。并且你的runnable有一个start()函数,它启动并启动本地线程并调用thread.start。像这样,您可以拥有一个线程对象列表。你也可以有一个访问器来获取线程。
public class Threaded extends other implements Runnable {
Thread localThread;
@Override
public void run() {
//...
}
public void start() {
localThread = new Thread(this);
localThread.start();
}
}