1]What is Non-blocking Concurrency and how is it different.
As others have mentioned, Non-blocking is a way of saying deadlock-free (meaning we shouldn't have a condition where progress halts entirely while threads are blocked, waiting for access).
What is meant by 'concurrency' is just that multiple computations are happening at the same time (concurrently).
2] I have heard that this is available in Java. Are there any particular scenarios we should use this feature
You want to use non-blocking algorithms when it is important that multiple threads can access the same resources concurrently, but we aren't as concerned with the order of access or the possible ramifications of interleaving action (more on this below).
3] Is there a difference/advantage of using one of these methods for a collection. What are the trade offs
.
Using the synchronized(list) block ensures that all of the actions performed within the block are seen as atomic. That is to say, as long as we only access the list from synchronized(list) blocks, all updates to the list will appear as if they happened at the same time within the block.
A synchronizedList (or synchronizedMap) object only ensures that individual operations are thread-safe. This means that two inserts will not occur concurrently. Consider the following loop:
for(int i=0; i < 4; i++){
list.add(Integer.toString(i));
}
If the list in use was a synchronizedList and this loop was executed on two different threads, then we may end up with {0,0,1,2,1,3,2,3} in our list, or some other permutation.
Why? Well, we are guaranteed that thread 1 will add 0-3 in that order and we are guaranteed the same of thread 2, however we have no guarantee of how they will interleave.
If, however, we wrapped this list in a synchronized(list) block:
synchronized(list){
for(int i=0; i < 4; i++){
list.add(Integer.toString(i));
}
}
We are guaranteed that the inserts from thread 1 and thread 2 will not interleave, but they will occur all at once. Our list will contain {0,1,2,3,0,1,2,3}. The other thread will block, waiting on list, until the first thread completes. We have no guarantee which thread will be first, but we are guaranteed it will finish before the other begins.
So, some trade-offs are:
We can create a deadlock when two (or more) threads are each waiting for a subset of resources held by another. If, for example, you had two lists: userList and movieList.
If thread 1 first acquires the lock to userList, then movieList, but thread two performs these steps in reverse (acquires the lock to movieList before userList), then we have opened ourself up for deadlock. Consider the following course of events:
Both threads are waiting for the other and neither can move forward. This is a blocking scenario, and since neither will relinquish its resource, we are deadlocked.