Saturday, January 5, 2013

Deadlock and Race condition

http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.
When Deadlock runs, it's extremely likely that both threads will block when they attempt to invoke bowBack. Neither block will ever end, because each thread is waiting for the other to exit bow.


http://stackoverflow.com/questions/34510/what-is-a-race-condition
A "race condition" exists when multithreaded (or otherwise parallel) code that would access a shared resource could do so in such as way as to cause unexpected results.
Take this example:

for ( int i = 0; i < 10000000; i++ )
{
  x = x + 1;
}

If you had 5 threads executing this code at once, the value of x WOULD NOT end up being 50,000,000. It would in fact vary with each run.
This is because, in order for each thread to increment the value of x, they have to do the following: (simplified, obviously)
Retrieve the value of x
Add 1 to the value of x
Store the value of x

Any thread can be at any step in this process at any time, and they can step on each other when a shared resource is involved. The state of x can be changed by another thread during the time between x is being read and when it is written back.
Let's say a thread retrieves the value of x, but hasn't stored it yet. Another thread can also retrieve thesame value of x (because no thread has changed it yet) and then they would both be storing the samevalue (x+1) back in x!
Example:
Thread 1: reads x, value is 7
Thread 1: add 1 to x, value is now 8
Thread 2: reads x,
value is 7
Thread 1: stores 8 in x
Thread 2: adds 1 to x, value is now 8
Thread 2:
stores 8 in x

Race conditions can be avoided by employing some sort of locking mechanism before the code that accesses the shared resource:

for ( int i = 0; i < 10000000; i++ )
{
  //lock x
  x = x + 1;
  //unlock x
}

Here, the answer comes out as 50,000,000 every time.
For more on locking, search for: mutex, semaphore, critical section, shared resource.

public class Deadlock {
   static class Friend {
       private final String name;
       public Friend(String name) {
           this.name = name;
       }
       public String getName() {
           return this.name;
       }
       public synchronized void bow(Friend bower) {
           System.out.format("%s: %s"
               + "  has bowed to me!%n",
               this.name, bower.getName());
           bower.bowBack(this);
       }
       public synchronized void bowBack(Friend bower) {
           System.out.format("%s: %s"
               + " has bowed back to me!%n",
               this.name, bower.getName());
       }
   }

   public static void main(String[] args) {
       final Friend alphonse =
           new Friend("Alphonse");
       final Friend gaston =
           new Friend("Gaston");
       Thread al = new Thread(new Runnable() {
           public void run() { alphonse.bow(gaston); }
       });
       al.setName("alphonse");
       al.start();
       new Thread(new Runnable() {
           public void run() { gaston.bow(alphonse); }
       }).start();
   }
}

No comments:

Post a Comment