Reputation: 2998
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
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
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
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
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
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
Reputation: 136022
Use a Queue, A will periodically poll the queue, B can put values to queue asynchroneously
Upvotes: 2