如何通过线程访问Runnable对象?
可能重复: 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? } }
我在java.lang.Thread
文档中看不到任何方法。
那么,我最好的答案是你可能应该使用List
而不是(或除了) List
。 或者您可能想要某种地图结构,以便可以从Thread访问Runnable。 (例如, java.util.HashMap
)
并发库很好地支持了这一点。 注意:如果您的任务抛出exception,则Future将保持此状态并在调用get()时抛出包装exception
ExecutorService executor = Executors.newSingleThreadedExecutor(); Future future = executor.submit(new Callable () { public String call() { return "world"; } }); String result = future.get();
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);
顺便说一句,在实际情况下,您需要使用Callable
和FutureTask
如果要返回异步计算的值,请查看Callable和FutureTask:
FutureTask task = new FutureTask(new Callable () { public String call() { return "world"; } }); new Thread(task).start(); String result = task.get();
如果您的线程有状态信息,请忘记Runnable并简单地扩展Thread,覆盖run方法。
我认为一般来说你可以/应该避免这样做,但是如果你真的需要这样做,那就不应该像MatrixFrog的建议那样(未经测试):
class RunnableReferencingThread extends Thread { public final Runnable runnable; public RunnableReferencingThread(Runnable r) { super(r); this.runnable = r; } }
?
这是你如何直接实现这一点。
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
使用更高级别的并发类。
我有同样的问题。 这是我的解决方案:
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; }
为了给出保罗克劳利解决方案的具体例子,我认为这是他的建议:
public class BackgroundJob extends Thread { private final JOB mJob; public BackgroundJob(JOB job) { super(job); mJob = job; } public JOB getJob() { return mJob; } }
您可以inheritanceThread,并添加您需要的方法。 您必须保留自己的目标Runnable副本并覆盖用于创建Thread的所有Thread构造函数,因为Thread的一些恼人的实现细节。
我想,如果可以的话,就是要恢复局面。 那么在这种情况下,一个好的解决方案是将线程存储在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(); } }
- 使用java.time生成随机LocalDate
- 调用getNextException以查看原因:如何使Hibernate / JPA显示数据库服务器消息以查找exception
- 如何在String.valueOf(int)中使用ArrayOutOfBoundsException?
- 禁用特定Java包的所有checkstyle检查
- BufferedReader比Scanner有什么好处
- 在多个XML文件中拆分XML
- java.lang.NoClassDefFoundError:javax / validation / ParameterNameProvider
- 何时在构造函数外部进行初始化?
- 使用Java进行NAT遍历