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?
The simplest way to execute a method asynchronously is to start executing the method by calling the delegate's BeginInvoke method, do some work on the main thread, and then call the delegate's EndInvoke method. EndInvoke might block the calling thread because it does not return until the asynchronous call completes.
Use the Result property on the asynchronous Task, like so: // Synchronous method. void Method()
In synchronous operations tasks are performed one at a time and only when one is completed, the following is unblocked. In other words, you need to wait for a task to finish to move to the next one. In asynchronous operations, on the other hand, you can move to another task before the previous one finishes.
Async/await helps you write synchronous-looking JavaScript code that works asynchronously. Await is in an async function to ensure that all promises that are returned in the function are synchronized. With async/await, there's no use of callbacks.
And if you’re looking at how to run an async method synchronously, you must not think it’s an issue anyway. Sometimes an asynchronous call is not necessary. If there’s a synchronous version of a library method already available and it will complete quickly, consider using that instead.
The only reason it comes into the discussion at all is that async is at least better than sync if your goal is to not block a thread, because sometimes, in some scenarios, it maybe might just run on a different thread. If you have any synchronous code in your async method (anything that's not awaiting something else) that code will always run sync.
So my understanding is as follows. The first method should be left as is, since none of the file operation methods have async versions and are therefore not likely naturally async.
However, Task -returning methods without the async keyword should return a Task with the exception. Often when developing sync and async versions of a method, you'll find that the only real difference between the two implementations is that one calls async versions of various methods while the other calls the sync versions.
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With