There are many overlaps between these two terms non-blocking and asynchronous. But still there are differences
As written [a]synchronous it means it is not synchronous:) this was very easy explanation.
Nevertheless it means don't wait for a response after you make an asynchronous call. So it will continue to process a job but once asynchronous call is done then it will be signaled by response
An other example might be http client to make request to server.
For instance one you made get request you hold a connection and wait for response.
But for asynchronous call you make a call and you create a callback and basically don't wait for response.
For an example of asynchronous client please check out apache asynchronous http client
So as written it means do not block incoming call for any reason give response right away.
So at this point differences between asynchronous call and non-blocking is
actually you are making synchronous call but your call not being blocked for any reason and you get response right away even though it wasn't
the one you expect:)
Ok since we start with mentioning with async call and non blocking call. I’d like to continue with
moving topic to concurrency models
Let’s start with most traditional model Shared memory which is mostly aim to get advantage of idle time of single cpu
like when one waiting for input meanwhile other do something else. Most java developers familiar with traditional multithreading in java.
And most of them know the problem like blocking contention, locking, deadlocks or problem like non-deterministic
switching from one thread to another which makes harder to decide system behavior and cause problems like race conditions.
And it’s hard to reproduce these problems.
One thread can execute while another is waiting is good approach for single cpu but now we are working on multicore machines
and we need to take advantage of parallel computing. Nowadays we have cpus with multicores because cpu manufacturers can’t
just infinitely increase clock rate for faster cpu which cause heating problem instead manufacturers add more cores inside the cpu.
So as a software engineer we need to fully utilize the capabilities offered by these processors. Simply we need to write applications
which take advantage multiple cores. Java threads are not optimized for parallel computing The Fork/Join Framework is.
The Fork/Join Framework enhances multithreaded programming in two important ways. First, it simplifies the creation and use of multiple threads.
Second, it automatically makes use of multiple processors.
In Message passing model all communications happen by means of messages. Instead of sharing a memory and lock-unlock approach
one sends message to other to do something or give a responsibility to do work. There is no shared state.
So think about you have multiple cores and they have encapsulate their state and doing given job and communicate through messaging.
An example of message passing model is actor model. In the actor model, each object is an actor. Think about actor is a lightweight thread
and not like traditional one it is very cheap to create and destroy one. If an actor want to get information about the internal state of another actor,
it will have to use messages to request this information. Actor itself single thread execution so no need to care about concurrency inside of the actor.
This way it is easy to program and test. Actor recieve message to do something without sharing anything with other and then once it finishes it sends message
and wait for another one. Importance in this model is that all communications are performed asynchronously.
This implies that the sender does not wait for a message to be received upon sending it, it immediately continues its execution
There are many actor libraries for different languages. Check out list of available libraries and at actor model
One thing need to be considered actors are hidden queues. You fill out queues with messages and actor pick messages one by one and process it.
This way it has some drawbacks like message lost or slow consumer fast producer or vice versa .
But there are many design patterns which aim to reduce to these sort of problems.
Scala has very nice actor library as known Akka akka.io they have very nice implementaion of actor model based on scala
and they have java api as well. And they have many patterns which address many issues and
you can find many solutions for different use cases at let it crash
At this post I want to emphasize that as a software engineers we need to fully utilize the capabilities of hardware that we are running our software.
Now we are building distributed cloud applications which aim to handle heavy load and become always responsive, available and fast.
This is not trivial problem it requires well analyzing running system and well designed application.
Please also keep in mind you can’t get your non-parallel system into running parallel system just making some part parallel.
It’s like max flow problem, to get more flow you need to analyze your system and increase capacity of pipes based on flow.
Check out Amdahl's law to get more information about limitation of improving your system. Amdahl's law