1

For example if I have thread A and thread B. Thread A is my main thread where most of the application runs but when I need a value fetched from MySQL or another external source I create a new thread (thread B).

What is the best way of returning the value from thread B to thread A for further processing without causing thread A to wait until the value is available?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user2248702
  • 2,741
  • 7
  • 41
  • 69
  • possible duplicate http://stackoverflow.com/questions/14148422/what-is-the-best-way-to-pass-information-between-threads – lakshman Jan 28 '14 at 07:47

6 Answers6

2

Use a Queue, A will periodically poll the queue, B can put values to queue asynchroneously

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • Sorry, I have edited the post to make it more clear but I would want thread A to continue to execute normally until a response is available. – user2248702 Jan 28 '14 at 07:53
  • It can continue to execute. But it still needs to poll every once in a while to do something when the response is ready. – Kayaman Jan 28 '14 at 08:01
2

You can use ScheduledThreadPoolExecutor which will return Future and you dont need to wait.

Sample Usage (From java Docs on Future)

interface ArchiveSearcher { String search(String target); }
 class App {
   ExecutorService executor = ...
   ArchiveSearcher searcher = ...
   void showSearch(final String target)
       throws InterruptedException {
     Future<String> future
       = executor.submit(new Callable<String>() {
         public String call() {
             return searcher.search(target);
         }});
     displayOtherThings(); // do other things while searching
     try {
       displayText(future.get()); // use future
     } catch (ExecutionException ex) { cleanup(); return; }
   }
 }

Same can be achieved from Future task too(visit above link, example are from there only)

The FutureTask class is an implementation of Future that implements Runnable, and so may be executed by an Executor. For example, the above construction with submit could be replaced by:

 FutureTask<String> future =
       new FutureTask<String>(new Callable<String>() {
         public String call() {
           return searcher.search(target);
       }});
     executor.execute(future);
Prateek
  • 12,014
  • 12
  • 60
  • 81
  • Why do you suggest constructing a FutureTask and passing it to Executor, while ExecutorService has a submit method, which constructs Future for you? – Mikhail Jan 28 '14 at 08:14
  • Well, that is not what OP wants, because the main thread will wait on `future.get()` anyway... – Adam Dyga Jan 28 '14 at 08:44
2

If you have a single task that needs to be done, you can use a Future and have the other Thread poll the (non-blocking) isDone() method whenever it is convenient.

If that task is executed frequently or you have many tasks to execute, using a ConcurrentLinkedQueue might be a better idea, which also comes in a variant that supports blocking till a result is delivered as LinkedBlockingQueue. Again: polling on the list whenever it is convenient will do the trick.

If you do not want to poll, you can instead work with a callback-functionality. For example if you use a Swing GUI, you can have the DB thread call invokeLater from the SwingUtilities class, so processing the request is done on the main Swing thread at the next possible time.

This is based on the EventQueue class, which might be more convenient to use in certain other scenarios.

TwoThe
  • 13,879
  • 6
  • 30
  • 54
0

If you don't want to deal with executors, just create a FutureTask and pass it to a new thread.

FutureTask<String> f = new FutureTask<String>(new Callable<String>() {
    @Override
    public String call() {
        return "";
    }
});
new Thread(f).start();
while (Thread.currentThread().isInterrupted()) {
    if (f.isDone()) {
        System.out.println(f.get());
        break;
    }
    //do smth else
}
Mikhail
  • 4,175
  • 15
  • 31
0

For thread B, declare a class that implements Runnable. For example:

public class MyClass implements Runnable
{
    private String input  = null;
    private String output = null;

    public MyClass(String input)
    {
        this.input = input;
    }

    public String getOutput()
    {
        return output;
    }

    public void run()
    {
        output = func(input);
    }
}

In thread A (which is your main thread), start thread B, and wait for it to complete only where you actually need its output. For example:

public String myFunc(String input) throws Exception
{
    MyClass object = new MyClass(input);
    Thread  thread = new Thread(object);

    thread.start();
    // Do whatever you wanna do...
    // ...
    // ...

    // And when you need the thread's output:
    thread.join();
    return object.getOutput();
}
barak manos
  • 29,648
  • 10
  • 62
  • 114
  • The main thread will have to wait on `thread.join()` which is not what OP wants – Adam Dyga Jan 28 '14 at 08:48
  • @Adam Dyga: Thanks. But can you please review the answer again? The main thread will wait **only** when it actually needs the value. In essence, OP should call `thread.join()` just before the point where the output of that thread is **required**. Until then, the main thread continues normally without waiting for anything. I wrote `myFunc` as an example (the contents of this function can be placed anywhere within the main thread). – barak manos Jan 28 '14 at 09:30
0

Organize your main thread as an event loop:

BlockingQueue<Runnable> eventQueue=
    new LinkedBlockingQueue<>();
for (;;) {
    Runnable nextEvent=eventQueue.take();
    nextEvent.run();
}

Thread B:

Result r=fetchFromDB();
eventQueue.put(new ResultHandler(r));

where ResultHandler is a Runnable which knows how to handle the result.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38