Issues with Multithreaded Programming: Part 3

By Ashish Khandelwal, June 23, 2011

In my previous articles “Issues with Multithreaded Programming: Part 1” and “Issues with Multithreaded Programming: Part 2” I have explained about four issues of Multithreading programming 1) Race Condition 2) DeadLock 3) LiveLock and 4) Priority Inversion. Continuing to my previous articles, in this article I have explained about following issues:

  • Two-Step Dances
  • Lock Convoys

Two-Step Dances

In “two-step dance” threads bounce between waking and waiting, not doing any work. This happens due to the way signaling models get implemented by developers.

Let’s take an example: sometimes when you signal an event while holding a lock and if the waking (signaled – Thread 2) thread needs to acquire a lock already held by signaling thread (Thread1), in this case the signaled thread (Thread 2) will only be awaked to find out that it has to wait again. The signaling thread (Thread 1) will awake again, release the lock. Once released, the signaled thread (Thread 2) will awake and get the lock. This is wasteful and increases the number of overall context switches. This situation is called the two-step dance, and can extend far beyond just two steps if many locks and events are involved.

Lock Convoys

Lock convoy occurs when multiple threads with equal priority compete repeatedly for the same lock. In this situation threads do progress, but each time the attempt to acquire the lock gets fails. This degrades the overall performance of the application because of additional overhead of repeated context switches and underutilization of scheduling process.

Lock convoy more occurs when there are more threads waiting at a lock than can be serviced. This situation is more common on server-side programs where locks get implemented to protect data needed by most clients.

For example: On an average, application gets eight requests per 100 milliseconds and uses eight threads to service these requests (because hosted on an 8-CPU machine). Each thread must hold a lock for 20 milliseconds to accomplish meaningful work. Access to this lock must be serialized, therefore it takes 160 milliseconds for all eight threads to enter and exit the lock. After the first exists, 140 milliseconds are required before ninth thread can access the lock. This scheme inherently will not scale, and there will be a continuously growing backup of requests. Over time, if the arrival rate does not decrease, client requests are apt to begin timing out, and a disaster will result.

I hope the information I have provided will help you :)

Dont forget to read about other issues of Multithreaded Programming @

Read Issues with Multithreaded Programming: Part 1 to understand about:

  • Race Condition
  • DeadLock

Read Issues with Multithreaded Programming: Part 2 to understand about:

  • LiveLock
  • Priority Inversion

3 Responses to “Issues with Multithreaded Programming: Part 3”

  1. Pinki says:

    Hay this is pinki again…

    all three articles on multithreading are good. nically explained…

    Thanks.

  2. Jonny says:

    Thanks for the post…

    We never realized the two setp dance will be the problem for the application.
    It seems now we have to look our code again to boost the performance.

    Thanks for the explaination.

  3. Rithesh says:

    Thanks for the post…

    Multithreading is always difficult to implement due the deadlock, race condition.
    It is always better to put munimum lock on shared resource.

    I liked your article

Leave a Reply