2

I made a thread like this one bellow:

public class MyThread implements Runnable {
  private int temp;

  public MyThread(int temp){
     this.temp=temp;
  }

  @Override
  public void run() {
    temp+=10;
    return;
  }

  public int getTemp() {
    return temp;
  }
}

but when i try to use temp by getTemp i get 0

class Main {
  MyThread foo = new MyThread(10);
  Thread a = new Thread(foo);
  a.start();
  int aa = foo.getTemp();       
  System.out.println(aa);
}

i just want to use the calculation i did in thread to be stored in some variables for later use.

TedTrippin
  • 3,525
  • 5
  • 28
  • 46
user3512121
  • 95
  • 1
  • 1
  • 6

5 Answers5

6

Or simply add

...
a.start();
a.join(); // Add this
...

to wait for the thread to finish before getting the result.

Your problem is that you're trying to get the result before it has been calculated. You should wait for the thread to finish before getting the result. This answer is perhaps not the best but is the simplest. As other people had already used the Executors class I didnt want to repeat their answers. I would, however, familiarise yourself with Thread and its methods before moving onto Executors to help you get a better understanding of threads as, from your post, it appears you may be a novice in this area.

Thanks to l4mpi (on the meta site) for pointing out the lack of explanation.

Community
  • 1
  • 1
TedTrippin
  • 3,525
  • 5
  • 28
  • 46
  • Thus significantly reducing the gain from using multiple threads. This is not an optimal solution. – Dariusz Sep 19 '14 at 08:28
  • 1- Its the simplest, most concise answer. 2- Op doesnt have multiple threads. 3- Someone already given an answer for use with multiple threads. 4- Go troll somewhere else. – TedTrippin Sep 19 '14 at 08:53
  • 2
    Because I think it should not be used for synchronizing parallel computing operations. I think that `Thread.join()` should be used only when the application is closing and the thread has some work to finish - at least I can't think of any other good use right now, maybe there is one. But not this. Besides: look at the hint at the *downvote* button, it says: "this answer is not useful". Not only do I deem it not useful, I think that it promotes bad practice. – Dariusz Sep 19 '14 at 09:00
  • This post is discussed on [meta](http://meta.stackoverflow.com/questions/271700/do-we-upvote-correctness-or-usefulness). – Patrick Hofman Sep 19 '14 at 10:02
  • 1
    There *are* times when you have to use an asynchronous process (or are forced to process on a different thread--see STA threads) yet also have to block the current thread until that process is complete. So there are instances where you'd have to do something like this. –  Sep 19 '14 at 16:31
4

Use Callable instead of a Runnable, it will return a Future that you can use to retrieve the value once it is done.

You can use a named class instead of a lambda expression if you want to.

import java.util.concurrent.*;

public class ReturnValueFromThread {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Object> foo = executor.submit(() -> {
            return doWork();
        });

        System.out.println("We will reach this line before doWork is done.");
        System.out.println(foo.get()); // Will wait until the value is complete
        executor.shutdown();
    }

    private static double doWork() throws Exception {
        Thread.sleep(2000);
        return Math.random();
    }
}
folkol
  • 4,752
  • 22
  • 25
1

You can try these code. By using Future you can hold the value return when the thread end:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author mike
 * @date Sep 19, 2014
 * @description
 */
public class Calc {
    private static class MyCallable implements Callable<Integer> {
        private int temp = 0;

        public MyCallable(int temp) {
            this.temp = temp;
        }

        @Override
        public Integer call() {
            temp += 10;
            return temp;
        }
    }

    public static void main(String[] args) {
        MyCallable foo = new MyCallable(10);
        try {
            Future<Integer> result = Executors.newCachedThreadPool().submit(foo);
            System.out.println(result.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}
D0n9X1n
  • 2,114
  • 1
  • 14
  • 17
0

In this case, you have to use Callable instead of Runnable (very similar): http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

public class MyThread implements Callable<Integer> { 

    private int temp;

    public MyThread(int temp){
         this.temp=temp;
    }
    @Override
    public Integer call() {
        temp+=10;
        return temp;
    }

}


public static void main(String[] args) throws InterruptedException, ExecutionException {
           ExecutorService service =  Executors.newSingleThreadExecutor();
           MyThread myTask = new MyThread(10);
           Future<Integer> future = service.submit(myTask);
           Integer result = future.get();
           System.out.println(result);
}
fmgp
  • 1,638
  • 17
  • 17
0

There are a few ways to "share" variables with Threads.

The problem with your code is that you are passing an int which is passed by value. This means that temp and this.temp is not the same variable.

Using a Future as other answers suggest is one way that you can share variables. Using a Future, you can ensure that the Thread has finished before actually fetching the result of that Threads execution so might be more relevant to you.

Other ways of sharing variables among Threads that are Thread-safe, but does not guarantee that the Thread has finished execution:

  • pass an AtomicInteger and use the set method to set value.
  • use a synchronized getter method that returns the Threads value.
Community
  • 1
  • 1
Ioannis Deligiannis
  • 2,679
  • 5
  • 25
  • 48