7

After doing lots of searching on Java, I really am very confused over the following questions:

  1. Why would I choose an asynchronous method over a multi-threaded method?

  2. Java futures are supposed to be non-blocking. What does non-blocking mean? Why call it non-blocking when the method to extract information from a Future--i.e., get()--is blocking and will simply halt the entire thread till the method is done processing? Perhaps a callback method that rings the church bell of completion when processing is complete?

  3. How do I make a method async? What is the method signature?

    public List<T> databaseQuery(String Query, String[] args){
      String preparedQuery = QueryBaker(Query, args);
      List<int> listOfNumbers = DB_Exec(preparedQuery); // time taking task
      return listOfNumbers;
    }
    

    How would this fictional method become a non blocking method? Or if you want please provide a simple synchronous method and an asynchronous method version of it.

2
  • one option is to start a new thread to do the future resolution, but that may not be always feasible. Commented Mar 27, 2016 at 7:37
  • dzone.com/articles/javautilconcurrentfuture Future promises to return a result(or rethrows an exception) sometime in the future. Use isDone() or get(timeout) to poll for completion. You may do something else until completion or submitting more Futures to an executor worker. If you need just one singlethread request-response synched all the time it may suit better to code traditional stuff. You need to create Callable<ResultObj> instance and submit it to an executor worker. Executor gives you a Future<ResultObj> promiser. Commented Mar 27, 2016 at 7:49

3 Answers 3

6

Why would I choose an asynchronous method over a multi-threaded method?

Asynchronous methods allow you to reduce the number of threads. Instead of tying up a thread in a blocking call, you can issue an asynchronous call and then be notified later when it completes. This frees up the thread to do other processing in the meantime.

It can be more convoluted to write asynchronous code, but the benefit is improved performance and memory utilization.

Java futures are supposed to be non-blocking. What does non-blocking mean? Why call it non-blocking when the method to extract information from a Future--i.e., get()--is blocking and will simply halt the entire thread till the method is done processing ? Perhaps a callback method that rings the church bell of completion when processing is complete?

Check out CompletableFuture, which was added in Java 8. It is a much more useful interface than Future. For one, it lets you chain all kinds of callbacks and transformations to futures. You can set up code that will run once the future completes. This is much better than blocking in a get() call, as you surmise.

For instance, given asynchronous read and write methods like so:

CompletableFuture<ByteBuffer> read();
CompletableFuture<Integer> write(ByteBuffer bytes);

You could read from a file and write to a socket like so:

file.read()
    .thenCompose(bytes -> socket.write(bytes))
    .thenAccept(count -> log.write("Wrote {} bytes to socket.", count)
    .exceptionally(exception -> {
        log.error("Input/output error.", exception);
        return null;
    });

How do I make a method async? What is the method signature?

You would have it return a future.

public CompletableFuture<List<T>> databaseQuery(String Query, String[] args);

It's then the responsibility of the method to perform the work in some other thread and avoid blocking the current thread. Sometimes you will have worker threads ready to go. If not, you could use the ForkJoinPool, which makes background processing super easy.

public CompletableFuture<List<T>> databaseQuery(String query, String[] args) {
    CompletableFuture<List<T>> future = new CompletableFuture<>();
    Executor executor = ForkJoinPool.commonPool();

    executor.execute(() -> {
        String preparedQuery = QueryBaker(Query, args);
        List<T> list = DB_Exec(preparedQuery); // time taking task
        future.complete(list);
    });
}
Sign up to request clarification or add additional context in comments.

Comments

4

why would I choose a Asynchronous method over a multi-threaded method

They sound like the same thing to me except asynchronous sounds like it will use one thread in the back ground.

Java futures is supposed to be non blocking ?

Non- blocking operations often use a Future, but the object itself is blocking, though only when you wait on it.

What does Non blocking mean?

The current thread doesn't wait/block.

Why call it non blocking when the method to extract information from a Future < some-object > i.e. get() is blocking

You called it non-blocking. Starting the operation in the background is non-blocking, but if you need the results, blocking is the easiest way to get this result.

and will simply halt the entire thread till the method is done processing ?

Correct, it will do that.

Perhaps a callback method that rings the church bell of completion when processing is complete ?

You can use a CompletedFuture, or you can just add to the task anything you want to do at the end. You only need to block on things which have to be done in the current thread.

You need to return a Future, and do something else while you wait, otherwise there is no point using a non-blocking operation, you may as well execute it in the current thread as it's simpler and more efficient.

You have the synchronous version already, the asynchronous version would look like

public Future<List<T>> databaseQuery(String Query, String[] args) {
     return executor.submit(() -> {
         String preparedQuery = QueryBaker(Query, args);
         List<int> listOfNumbers = DB_Exec(preparedQuery); // time taking task
         return listOfNumbers;
     });
}

Comments

2

I'm not a guru on multithreading but I'm gonna try to answer these questions for my sake as well

why would I choose a Asynchronous method over a multi-threaded method ? (My problem: I believe I read too much and now I am myself confused)`


Multi-threading is working with multiple threads, there isn't much else to it. One interesting concept is that multiple threads cannot work in a truly parallel fashion and thus divides each thread into small bits to give the illusion of working in parallel.

1

One example where multithreading would be useful is in real-time multiplayer games, where each thread corresponds to each user. User A would use thread A and User B would use thread B. Each thread could track each user's activity and data could be shared between each thread.

2

Another example would be waiting for a long http call. Say you're designing a mobile app and the user clicks on download for a file of 5 gigabytes. If you don't use multithreading, the user would be stuck on that page without being able to perform any action until the http call completes.

It's important to note that as a developer multithreading is only a way of designing code. It adds complexity and doesn't always have to be done.


Now for Async vs Sync, Blocking vs Non-blocking

These are some definitions I found from http://doc.akka.io/docs/akka/2.4.2/general/terminology.html

Asynchronous vs. Synchronous

A method call is considered synchronous if the caller cannot make progress until the method returns a value or throws an exception. On the other hand, an asynchronous call allows the caller to progress after a finite number of steps, and the completion of the method may be signalled via some additional mechanism (it might be a registered callback, a Future, or a message).

A synchronous API may use blocking to implement synchrony, but this is not a necessity. A very CPU intensive task might give a similar behavior as blocking. In general, it is preferred to use asynchronous APIs, as they guarantee that the system is able to progress. Actors are asynchronous by nature: an actor can progress after a message send without waiting for the actual delivery to happen.

Non-blocking vs. Blocking

We talk about blocking if the delay of one thread can indefinitely delay some of the other threads. A good example is a resource which can be used exclusively by one thread using mutual exclusion. If a thread holds on to the resource indefinitely (for example accidentally running an infinite loop) other threads waiting on the resource can not progress. In contrast, non-blocking means that no thread is able to indefinitely delay others.

Non-blocking operations are preferred to blocking ones, as the overall progress of the system is not trivially guaranteed when it contains blocking operations.

I find that async vs sync refers more to the intent of the call whereas blocking vs non-blocking refers to the result of the call. However, it wouldn't be wrong to say usually asynchronous goes with non-blocking and synchronous goes with blocking.


2> Java futures is supposed to be non blocking ? What does Non blocking mean? Why call it non blocking when the method to extract information from a Future < some-object > i.e. get() is blocking and will simply halt the entire thread till the method is done processing ? Perhaps a callback method that rings the church bell of completion when processing is complete ?

Non-blocking do not block the thread that calls the method.

Futures were introduced in Java to represent the result of a call, although it may have not been complete. Going back to the http file example, Say you call a method like the following

Future<BigData> future = server.getBigFile(); // getBigFile would be an asynchronous method
System.out.println("This line prints immediately");

The method getBigFile would return immediately and proceed to the next line of code. You would later be able to retrieve the contents of the future (or be notified that the contents are ready). Libraries/Frameworks like Netty, AKKA, Play use Futures extensively.

How do I make a method Async? What is the method signature?

I would say it depends on what you want to do.

If you want to quickly build something, you would use high level functions like Futures, Actor models, etc. something which enables you to efficiently program in a multithreaded environment without making too many mistakes.

On the other hand if you just want to learn, I would say it's better to start with low level multithreading programming with mutexes, semaphores, etc.

Examples of codes like these are numerous in google if you just search java asynchronous example with any of the keywords I have written. Let me know if you have any other questions!

2 Comments

In that multiplayer example, wouldn't the sharing of data create race conditions or data inconsistencies ?
That's why it becomes important whether a data structure is thread safe or not. Thread safe data structures can be accessed from multiple threads....safely. Also if too many threads access the same resource, that could be a reason for poor performance=(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.