如何通过线程访问Runnable对象?

时间:2010-02-20 00:47:11

标签: java multithreading concurrency

可能重复: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?
    }
}

11 个答案:

答案 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,在实际情况下,您需要使用CallableFutureTask

答案 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();
    }

}