user2248702
user2248702

Reputation: 2998

Return result of thread to a separate thread

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?

Upvotes: 1

Views: 206

Answers (6)

Alexei Kaigorodov
Alexei Kaigorodov

Reputation: 13535

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.

Upvotes: 0

TwoThe
TwoThe

Reputation: 14269

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.

Upvotes: 2

Mikhail
Mikhail

Reputation: 4223

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
}

Upvotes: 0

barak manos
barak manos

Reputation: 30136

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

Upvotes: 0

Prateek
Prateek

Reputation: 12242

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

Upvotes: 2

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136022

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

Upvotes: 2

Related Questions