views:

309

answers:

5

Possible duplicate: 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:

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?
    }
}
+2  A: 

I don't see any way to do it in the java.lang.Thread docs.

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 map structure so that you can access the Runnable from the Thread. (For example, java.util.HashMap<java.lang.Thread, java.lang.Runnable>)

Platinum Azure
You can use code quotes to directly just use `<>`'s, wrapping the `List<Runnable>` with `'s
Tanzelax
@Tanzelax: Oh wow, I knew that too. Why I didn't think of using that to format my code, I don't know. All I can say is, it's been a really long day. Thanks for the tip.
Platinum Azure
I'm curious about the downvote. Whoever did it, care to explain?
Platinum Azure
+2  A: 
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

splix
So in summary, there's no way it can be done, right? You need to keep a reference to both the Thread and the Runnable.I'd be grateful if you could substantiate your claim about needing Callable and FutureTask.
Platinum Azure
Yes, you need a reference to object you running and that returns result to you, a `Runnable` at this case.`Callable` and `FutureTask` is more appropriate way to do things that you want.
splix
I guess I'm just not seeing it.
Platinum Azure
+1  A: 

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.

Stephen C
+2  A: 

If you want to return the value of an asynchronous calculation, look at Callable and FutureTask:

FutureTask<String> task = new FutureTask(new Callable<String>() {
   public String call() {
      return "world";
   }
});
new Thread(task).start();
String result = task.get();
Thilo
+1  A: 

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()

ExecutorService executor = Executors.newSingleThreadedExecutor();

Future<String> future = executor.submit(new Callable<String>() { 
   public String call() { 
      return "world"; 
   } 
}); 

String result = future.get(); 
Peter Lawrey
You probably want to shutdown the executor afterwards.
Thilo