views:

208

answers:

5

1]What is Non-blocking Concurrency and how is it different than Normal Concurrency using Threads. Why dont we use "non-blocking" Concurrency in all the scenarios where concurrency is reuired.. are there any overheads for "non-blocking"

2] I have heard that this is available in Java. Are there any particular scenarios we should use this feature

3] Is there a difference/advantage of using one of these methods for a collection. What are the trade offs

class List   
{  
    private final ArrayList<String> list = new ArrayList<String>();

    void add(String newValue) 
    {
        synchronized (list)
        {
            list.add(newValue);
        }
    }
}  

OR

private final ArrayList<String> list = Collections.synchronizedList(); 

The questions are more from a learning/understanding point of view. Thanks for attention.

+2  A: 

1) Non-blocking synchronization means that the risk of deadlocks is removed. No one thread will wait to get a lock held by another thread "forever".

2) More on non-blocking synchronization algorithms in java.

Lars Andren
A: 
  1. Wikipedia is a great resource for any Computer Science student. Here is an article on Non-blocking synchronization - http://en.wikipedia.org/wiki/Non-blocking_synchronization

  2. Non-blocking synchronization is available in any language, it is how the programmer defines their multi-threaded application.

  3. You should only use locking (i.e. synchronized (list) ) when necessary due to the time it takes to acquire the lock. In Java, the Vector is a thread safe data structure that is very similar to Java's ArrayList.

Eric U.
+2  A: 

1) What is Non-blocking Concurrency and how is it different.

A task (thread) is non-blocking when it doesn't cause other tasks (threads) to wait until the task is finished.

2) I have heard that this is available in Java. Are there any particular scenarios we should use this feature

Java supports at its own multithreading. You can take benefit of it to run multiple tasks concurrently. When well written and implemented, this may speed up the program when running at a machine with multiple logical CPU's. To start, there are java.lang.Runnable and java.lang.Thread as low level concurrency implementations. Then there is high level concurrency in flavor of the java.util.concurrent API.

3) Is there a difference/advantage of using one of these methods for a collection. What are the trade offs

I would use Collections#synchronizedList(), not only because that's more robust and convenient, but also because a Map isn't a List. There's no need to attempt to homegrow one when the API already offers the facility.


That said, there's a Sun tutorial about Concurrency. I recommend you to get yourself through it.

BalusC
+3  A: 

What is Non-blocking Concurrency and how is it different.

Formal:

In computer science, non-blocking synchronization ensures that threads competing for a shared resource do not have their execution indefinitely postponed by mutual exclusion. A non-blocking algorithm is lock-free if there is guaranteed system-wide progress; wait-free if there is also guaranteed per-thread progress. (wikipedia)

Informal: One of the most advantageous feature of non-blocking vs. blocking is that, threads does not have to be suspended/waken up by the OS. Such overhead can amount to 1ms to a few 10ms, so removing this can be a big performance gain. In java, it also means that you can choose to use non-fair locking, which can have much more system throughput than fair-locking.

I have heard that this is available in Java. Are there any particular scenarios we should use this feature

Yes, from Java5. In fact, in Java you should basically try to meet your needs with java.util.concurrent as much as possible (which happen to use non-blocking concurrency a lot, but you don't have to explicitly worry in most cases). Only if you have no other option, you should use synchronized wrappers (.synchronizedList() etc.) or manual synchronize keyword. That way, you end up most of the time with more maintainable, better performing apps.

Non-blocking concurrency is particularly advantageous when there is a lot of contention. Obviously you can't use it when you need blocking (fair-locking, event-driven stuff, queue with maximum length etc.), but if you don't need that, non-blocking concurrency basically always performs better.

Is there a difference/advantage of using one of these methods for a collection. What are the trade offs

Both are basically equal (byte code should be basically equal). But I suggest to use Collections.synchronized because it's shorter = smaller room to screw up!

Enno Shioji
+1  A: 

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:

  • With a syncrhonizedList, you can insert without explicitly using a synchronized block.
  • A syncrhonizedList might give you a false sense of security, since you may naively believe successive opertaions on one thread to be atomic, when only individual operations are atomic
  • Using a syncrhonized(list) block must be done with care, because we are in a position to create deadlock (more below).

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:

  1. Thread 1 gets lock to userList
  2. Thread 2 gets lock to movieList
  3. Thread 1 tries to get lock to movieList, waits on Thread 2 to release
  4. Thread 2 tries to get lock to userList, waits on Thread 1 to release

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.

Ed Gonzalez
Your enumeration of events on the two lists is not accurate. should be #1 userlist, #2 movieList, #1 movieList (block), #2 userList (block)
harschware
Thanks harschware! Fixed.
Ed Gonzalez
Thanks Ed for the answers. I specifically assumed only one add operation inside a synchronized block. If we compare a synchronized link Vs a List which can add multiple elements synchronized in a block then it is not apple to apples.In general if both perform same functionality of adding one element at a time as in my question, would you prefer one over the other ?
p1
I'd probably prefer a synchronized(list) block over the synchronizedList, simply because I feel it makes the intent more explicit where we use it.
Ed Gonzalez