What's the best way to make a synchronous version of an asynchronous method in Java?
Say you have a class with these two methods:
asyncDoSomething(); // Starts an asynchronous task
onFinishDoSomething(); // Called when the task is finished
How would you implement a synchronous doSomething() that does not return until the task is finished?
Have a look at CountDownLatch. You can emulate the desired synchronous behaviour with something like this:
private CountDownLatch doneSignal = new CountDownLatch(1);
void main() throws InterruptedException{
asyncDoSomething();
//wait until doneSignal.countDown() is called
doneSignal.await();
}
void onFinishDoSomething(){
//do something ...
//then signal the end of work
doneSignal.countDown();
}
You can also achieve the same behaviour using CyclicBarrier with 2 parties like this:
private CyclicBarrier barrier = new CyclicBarrier(2);
void main() throws InterruptedException{
asyncDoSomething();
//wait until other party calls barrier.await()
barrier.await();
}
void onFinishDoSomething() throws InterruptedException{
//do something ...
//then signal the end of work
barrier.await();
}
If you have control over the source-code of asyncDoSomething() I would, however, recommend redesigning it to return a Future<Void> object instead. By doing this you could easily switch between asynchronous/synchronous behaviour when needed like this:
void asynchronousMain(){
asyncDoSomethig(); //ignore the return result
}
void synchronousMain() throws Exception{
Future<Void> f = asyncDoSomething();
//wait synchronously for result
f.get();
}
Related
I am writing a simple thread that simply run a process and reads the InputStream.
While reading the input, if it finds a certain string it sets a boolean to true.
Then when I need to check that boolean I usually do this:
thread.start();
//some other code
thread.join();
thread.getBoolean();
Or should I instead use Callable along with Future? If so, the correct use would be like this?
Callable<Boolean> myTask = new Task();
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Boolean> future = executorService.submit(myTask);
//some other code
Boolean output = future.get();
System.out.println(output);
executorService.awaitTermination(3, TimeUnit.SECONDS);
executorService.shutdownNow();
In my opinion, it is much better to use interfaces for asynchronous events like this. It is clean, faster and reliable.
Instead of a bare thread class, we would implement a string processor class that has a listener interface, and a process method that would take the stream and as well as the string to look for within the stream. So the approximate implementatin would be as following:
StringProcessor.java
class StringProcessor {
public interface StringProcessorListener {
void onStringProcessingFinish(boolean found);
}
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private StringProcessorListener listener;
public StringProcessor(StringProcessorListener listener) {
this.listener = listener;
}
public void process(InputStream inputStream, String strToFind) {
executorService.execute(()-> {
// Do the processing here...
while(inputStream.availlable() > 0) {
// Processing... maybe some string building or something else...
// Processing code goes here...
// A string built check it out
if(str.equals(strToFind)) {
// The string what we look for is found, notify the listener with true
listener.onStringProcessingFinish(true);
return;
}
// If reached here then the string not found, notify with false
listener.onStringProcessingFinish(false);
}
});
}
}
We would make use of this class from a superior class like following:
YourMainOrSuperiorClass.java
class YourMainOrSuperiorClass {
public static void main(String[] args) {
// Insantiate or get an input stream from where you wish...
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
// Search a string using the processor class
new StringProcessor(new StringProcessorListener {
#Override
public void onStringProcessingFinish(boolean found) {
if(found) {
// The string has been found, handle it
}
else {
// The String has not been found, handle it
}
}
})
.process(bufferedInputStream, "String to find");
// Maybe some more stuff to process from here...
}
}
As you can see, no need to block any thread using async interface patterns. When you invoke the StringProcessor.process() method, it will process the string within its internal thread without blocking the main thread, and you don't have to wait it to finish, on the contrary you can process more code meanwhile.
In the meantime, the StringProcessor will call the listener's onStringProcessingFinish() method as soon as the result is available and it will handled asynchronously from main thread while the main thread is taking care of something else.
Note that main thread should not return until the result is delivered in case of you need to update some UI elements or something else in the main thread. If this is the case you can manage it using a boolean flag, when main thread has been executed all of its stuff then enters to a busy waiting using that flag until the result is delivered. Once the result has delivered you can set that boolean flag accordingly then. It is like some kind of using the thread blocking method stuff.
I have a presentation class storing an XYChart.Series object and updating it by observing the model. The Series updating is done by using Platform.runLater(...)
I want to unit-test this, making sure the commands in runLater are performed correctly. How do I tell the unit-test to wait for the runLater commands to be done?
Right now all I do is Thread.Sleep(...) on the test-thread to give the FXApplicationThread the time to complete, but that sounds stupid.
The way I solved it is as follows.
1) Create a simple semaphore function like this:
public static void waitForRunLater() throws InterruptedException {
Semaphore semaphore = new Semaphore(0);
Platform.runLater(() -> semaphore.release());
semaphore.acquire();
}
2) Call waitForRunLater() whenever you need to wait. Because Platform.runLater() (according to the javadoc) execute runnables in the order they were submitted, you can just write within a test:
...
commandThatSpawnRunnablesInJavaFxThread(...)
waitForRunLater(...)
asserts(...)`
which works for simple tests
To have it more in AssertJ style syntax, you can do something like this:
#Test
public void test() throws InterruptedException {
// do test here
assertAfterJavaFxPlatformEventsAreDone(() -> {
// do assertions here
}
}
private void assertAfterJavaFxPlatformEventsAreDone(Runnable runnable) throws InterruptedException {
waitOnJavaFxPlatformEventsDone();
runnable.run();
}
private void waitOnJavaFxPlatformEventsDone() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
Platform.runLater(countDownLatch::countDown);
countDownLatch.await();
}
}
You could use a CountDownLatch which you create before the runLater and count down at the end of the Runnable
When I do async call using ExecutorService, it returns Future Object. Based on the boolean value it returns, I have to log the status of the async call.
But when I try to call the method get method from the future object, it blocks the main thread execution.
Is it possible to unblock the main thread execution?
public class FutureExample {
static HystrixCommand<Boolean> hystrixCommand;
public FutureExample(HystrixCommand<Boolean> hystrixCommand){
FutureExample.hystrixCommand = hystrixCommand;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
Boolean something = asyncCall();
if(something) {
System.out.println("Future task is done");
}
System.out.println("Don't wait for async call");
}
private static Boolean asyncCall() throws InterruptedException, ExecutionException {
Future<Boolean> response = hystrixCommand.queue(); // Aysnc Call to remote server
return response.get(); //this is blocking main thread
}
}
The good thing about futures is to be able to release threads until the answer arrives.
So I recommend you to use a Future implementation, like CompletableFuture:
final ExecutorService executorService = Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync(() -> {
try {
return hystrixCommand.queue();
} catch (Exception e) {
return false;
}
}, executorService);
This will work on another thread and when that future is over it will be done.
According to JavaDocs, get() method waits if necessary for the computation to complete, and then retrieves its result.
If you want to get the result once the task is completed, use isDone() function, which returns true if the task completed (normally, exceptionally, etc.). And invoke get() afterwards.
Also, you can use get(long timeout, TimeUnit unit) function to wait only for the given period of time. In this case the main thread will be "unblocked" automatically if either the time is out or the task has completed.
If you need to execute code in the main thread while the async task is running, you will need to redesign your asyncCall method to make it return a future instead.
An example:
private static Future<Boolean> asyncCall()
throws InterruptedException, ExecutionException {
return hystrixCommand.queue();
}
This way, the main method makes the call regarding when to block/wait:
public static void main(String[] args)
throws InterruptedException, ExecutionException {
Future<Boolean> something = asyncCall();
//do something while async call is running
//to check whether it's done running:
if(something.isDone()) {
System.out.println("Future task is done");
}
//when you're finally ready to wait:
System.out.println("Waiting for async call to finish");
Boolean result = something.get();
}
I am calling some service that returns a response thru some callback function.
I used thread to call this service so that it is running in its own process.
The thread is called in my Main thread.
My question is how can I optimize my busy while loop in calling this service.
Sometimes the service fails and it is okay to just continue to retry looping in until a good response is received.
public class ProcessResponse extends Thread
boolean isOK = false;
public void responseReturned(Response response){
//more code
if(response.OK){
//process result
isOK = true;
}
}
public void run(){
while(true){
// call service
Thread.sleep(1000);
if(isOK)
break;
}
}
}
UPDATE 2:
My next line of thinking is just to use latch
public class ProcessResponse extends Thread
boolean isOK = false;
CountDownLatch latch = new CountDownLatch(1);
public void responseReturned(Response response){
//more code
if(response.OK){
//process result
isOK = true;
}
latch.countDown();
}
public void run(){
while(!isOK){
// call service
try {
latch.await();
} catch (InterruptedException e) {
//handle interruption
}
latch = new CountDownLatch(1);
}
}
}
There is no sleep command but I am not sure if reinitializing the latch is a good approach. The service sometimes takes time to return.
Note..I haven't tried this code yet.. I just type it in so I am not sure if this will work.
There are lot of options that are fortunately available in JAVA 5 which you can use:
1) Cyclic Barrier:
Create a cyclic barrier of 2 and as the responseReturned will be called through main thread, you can simply put cyclic barrier await function to implement this. It has advantage that you can reuse the same barrier again and again without need to reinialize it.
2) CountDown Latch
Create a countdown latch of 1 and as soon as the responseReturned call the countdown function of latch, the await function in run will allow it to move ahead. It has a disadvantage that you have to reinitialize latch in case you want to reuse it.
3) ExecutorService
You can also use ExecutorService and can call future object get method to wait till proper response is returned.
4) Semaphore You can also use aquire before calling the service and release it in responseReturned. In run you can again call aquire post call to wait till response is returned.
All of them will allow you to implement the functionality with almost similar efficiency.
Hope that helps.
Future interface may be used for these kind of interactions along with ExecutorService I guees. Once you submit a request ,you can set the timeout for the callback etc.
Future<String> futureTask = executorService.submit(callable);
String result = null;
try {
result = futureTask.get(500, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
I have few asynchronous tasks running and I need to wait until at least one of them is finished (in the future probably I'll need to wait util M out of N tasks are finished).
Currently they are presented as Future, so I need something like
/**
* Blocks current thread until one of specified futures is done and returns it.
*/
public static <T> Future<T> waitForAny(Collection<Future<T>> futures)
throws AllFuturesFailedException
Is there anything like this? Or anything similar, not necessary for Future. Currently I loop through collection of futures, check if one is finished, then sleep for some time and check again. This looks like not the best solution, because if I sleep for long period then unwanted delay is added, if I sleep for short period then it can affect performance.
I could try using
new CountDownLatch(1)
and decrease countdown when task is complete and do
countdown.await()
, but I found it possible only if I control Future creation. It is possible, but requires system redesign, because currently logic of tasks creation (sending Callable to ExecutorService) is separated from decision to wait for which Future. I could also override
<T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable)
and create custom implementation of RunnableFuture with ability to attach listener to be notified when task is finished, then attach such listener to needed tasks and use CountDownLatch, but that means I have to override newTaskFor for every ExecutorService I use - and potentially there will be implementation which do not extend AbstractExecutorService. I could also try wrapping given ExecutorService for same purpose, but then I have to decorate all methods producing Futures.
All these solutions may work but seem very unnatural. It looks like I'm missing something simple, like
WaitHandle.WaitAny(WaitHandle[] waitHandles)
in c#. Are there any well known solutions for such kind of problem?
UPDATE:
Originally I did not have access to Future creation at all, so there were no elegant solution. After redesigning system I got access to Future creation and was able to add countDownLatch.countdown() to execution process, then I can countDownLatch.await() and everything works fine.
Thanks for other answers, I did not know about ExecutorCompletionService and it indeed can be helpful in similar tasks, but in this particular case it could not be used because some Futures are created without any executor - actual task is sent to another server via network, completes remotely and completion notification is received.
simple, check out ExecutorCompletionService.
ExecutorService.invokeAny
Why not just create a results queue and wait on the queue? Or more simply, use a CompletionService since that's what it is: an ExecutorService + result queue.
This is actually pretty easy with wait() and notifyAll().
First, define a lock object. (You can use any class for this, but I like to be explicit):
package com.javadude.sample;
public class Lock {}
Next, define your worker thread. He must notify that lock object when he's finished with his processing. Note that the notify must be in a synchronized block locking on the lock object.
package com.javadude.sample;
public class Worker extends Thread {
private Lock lock_;
private long timeToSleep_;
private String name_;
public Worker(Lock lock, String name, long timeToSleep) {
lock_ = lock;
timeToSleep_ = timeToSleep;
name_ = name;
}
#Override
public void run() {
// do real work -- using a sleep here to simulate work
try {
sleep(timeToSleep_);
} catch (InterruptedException e) {
interrupt();
}
System.out.println(name_ + " is done... notifying");
// notify whoever is waiting, in this case, the client
synchronized (lock_) {
lock_.notify();
}
}
}
Finally, you can write your client:
package com.javadude.sample;
public class Client {
public static void main(String[] args) {
Lock lock = new Lock();
Worker worker1 = new Worker(lock, "worker1", 15000);
Worker worker2 = new Worker(lock, "worker2", 10000);
Worker worker3 = new Worker(lock, "worker3", 5000);
Worker worker4 = new Worker(lock, "worker4", 20000);
boolean started = false;
int numNotifies = 0;
while (true) {
synchronized (lock) {
try {
if (!started) {
// need to do the start here so we grab the lock, just
// in case one of the threads is fast -- if we had done the
// starts outside the synchronized block, a fast thread could
// get to its notification *before* the client is waiting for it
worker1.start();
worker2.start();
worker3.start();
worker4.start();
started = true;
}
lock.wait();
} catch (InterruptedException e) {
break;
}
numNotifies++;
if (numNotifies == 4) {
break;
}
System.out.println("Notified!");
}
}
System.out.println("Everyone has notified me... I'm done");
}
}
As far as I know, Java has no analogous structure to the WaitHandle.WaitAny method.
It seems to me that this could be achieved through a "WaitableFuture" decorator:
public WaitableFuture<T>
extends Future<T>
{
private CountDownLatch countDownLatch;
WaitableFuture(CountDownLatch countDownLatch)
{
super();
this.countDownLatch = countDownLatch;
}
void doTask()
{
super.doTask();
this.countDownLatch.countDown();
}
}
Though this would only work if it can be inserted before the execution code, since otherwise the execution code would not have the new doTask() method. But I really see no way of doing this without polling if you cannot somehow gain control of the Future object before execution.
Or if the future always runs in its own thread, and you can somehow get that thread. Then you could spawn a new thread to join each other thread, then handle the waiting mechanism after the join returns... This would be really ugly and would induce a lot of overhead though. And if some Future objects don't finish, you could have a lot of blocked threads depending on dead threads. If you're not careful, this could leak memory and system resources.
/**
* Extremely ugly way of implementing WaitHandle.WaitAny for Thread.Join().
*/
public static joinAny(Collection<Thread> threads, int numberToWaitFor)
{
CountDownLatch countDownLatch = new CountDownLatch(numberToWaitFor);
foreach(Thread thread in threads)
{
(new Thread(new JoinThreadHelper(thread, countDownLatch))).start();
}
countDownLatch.await();
}
class JoinThreadHelper
implements Runnable
{
Thread thread;
CountDownLatch countDownLatch;
JoinThreadHelper(Thread thread, CountDownLatch countDownLatch)
{
this.thread = thread;
this.countDownLatch = countDownLatch;
}
void run()
{
this.thread.join();
this.countDownLatch.countDown();
}
}
If you can use CompletableFutures instead then there is CompletableFuture.anyOf that does what you want, just call join on the result:
CompletableFuture.anyOf(futures).join()
You can use CompletableFutures with executors by calling the CompletableFuture.supplyAsync or runAsync methods.
Since you don't care which one finishes, why not just have a single WaitHandle for all threads and wait on that? Whichever one finishes first can set the handle.
See this option:
public class WaitForAnyRedux {
private static final int POOL_SIZE = 10;
public static <T> T waitForAny(Collection<T> collection) throws InterruptedException, ExecutionException {
List<Callable<T>> callables = new ArrayList<Callable<T>>();
for (final T t : collection) {
Callable<T> callable = Executors.callable(new Thread() {
#Override
public void run() {
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
}
}
}
}, t);
callables.add(callable);
}
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(POOL_SIZE);
ExecutorService executorService = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 0, TimeUnit.SECONDS, queue);
return executorService.invokeAny(callables);
}
static public void main(String[] args) throws InterruptedException, ExecutionException {
final List<Integer> integers = new ArrayList<Integer>();
for (int i = 0; i < POOL_SIZE; i++) {
integers.add(i);
}
(new Thread() {
public void run() {
Integer notified = null;
try {
notified = waitForAny(integers);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("notified=" + notified);
}
}).start();
synchronized (integers) {
integers.wait(3000);
}
Integer randomInt = integers.get((new Random()).nextInt(POOL_SIZE));
System.out.println("Waking up " + randomInt);
synchronized (randomInt) {
randomInt.notify();
}
}
}