Monday, September 3, 2012

Avoiding dead locks


How to avoid deadlock in Java is one of the question which is flavor of the season for multithreading , asked more at a senior level and with lots of follow up questions , though question looks very basic but most of developer get stuck once you start going deep.

Question starts with "What is deadlock ?"
answer is simple , when two or more threads waiting for each other to release lock and get stuck for infinite time , situation is called deadlock . it will only happen in case of multitasking.

How do you detect deadlock in Java ?though this could have many answers , my version is first I would look the code if I see nested synchronized block or calling one synchronized method from other or trying to get lock on different object then there is good chance of deadlock if developer is not very careful.

Once you answer this , they may ask you to write code which will result in deadlock ?

Here is the simple example:

public void method1(){
synchronized(String.class){
System.out.println("Aquired lock on String.class object");
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
}
}
}

public void method2(){
synchronized(Integer.class){
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}

If method1() and method2() both will be called by two or many threads , there is a good chance of deadlock because if thead 1 aquires lock on Sting object while executing method1() and thread 2 acquires lock on Integer object while executing method2() both will be waiting for each other to release lock on Integer and String to proceed further which will never happen.Now interviewer comes to final part , one of the most important in my view ,

How to fix deadlock ? or How to avoid deadlock in Java ?


if you have looked above code carefully you may have figured out that real reason for deadlock is not multiple threads but the way they access lock , if you provide an ordered access then problem will be resolved , here is the fixed version.

public void method1(){
synchronized(Integer.class){
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}
public void method2(){
synchronized(Integer.class){
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}

Now there would not be any deadlock because both method is accessing lock on Integer and String object in same order . so if thread A acquires lock on Integer object , thread B will not proceed until thread A releases Integer lock , same way thread A will not be blocked even if thread B holds String lock because now thread B will not expect thread A to release Integer lock to proceed further.

Java Puzzle

Java puzzle on equal and == comparision operators:


public
class Test {
public static void main(String[] args) {
int x = 7;
Integer y =
new Integer(7);
System.
out.println(x == 7);
System.
out.println(y.equals(x));
}
}

Output:

true
true

Singleton Design Pattern


Approach 1: Regular singleton

package

patterns;
public
class Singleton {
private static Singleton myObject = null;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (myObject== null) {
myObject = new Singleton();
}
return myObject;
}
}


Approach 2: Double Lock check

package
patterns;
public
class SingletonDoubleLock {
private static SingletonDoubleLock myObject = null;
private SingletonDoubleLock() {
}
public static SingletonDoubleLock getInstance() {
if (myObject == null) {
synchronized (SingletonDoubleLock.class) {
if (myObject == null) {
myObject = new SingletonDoubleLock();
}
}
}
return myObject;
}
}


Aproach 3: Early Initilization

package
patterns;
public
class SingletonEarly {
private static SingletonEarly myObject = new SingletonEarly();
private SingletonEarly() {
}
public static SingletonEarly getInstance() {
return myObject;
}
}

Producer Consumer Problem


Examle for Producer - consumer problem using Java threads:

import
java.util.Stack;
 
public
class ManfacturingUnit {
private static boolean isAvailable = false;
private static Stack<Integer> basket = new Stack<Integer>();
public static void main(String[] args) {
ManfacturingUnit manfacturingUnit =
new ManfacturingUnit();
manfacturingUnit.
new Producer().start();
manfacturingUnit.
new Consumer().start();
}
class Consumer extends Thread {
@Override
public void run() {
for (int i = 1; i < 10;) {
synchronized (basket) {
if (isAvailable) {
System.
out.println("Consume->"+ basket.pop());
basket.notify();
isAvailable = false;
i++;
}
else {
try {
basket.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Producer extends Thread {
@Override
public void run() {
for (int i = 1; i < 10;) {
synchronized (basket) {
if (!isAvailable) {
basket.push(i);
System.
out.println("Produced->"+ i);
basket.notify();
isAvailable = true;
i++;
}
else {
try {
basket.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}


Output:
Produced->1
Consume->1
Produced->2
Consume->2
Produced->3
Consume->3
Produced->4
Consume->4
Produced->5
Consume->5
Produced->6
Consume->6
Produced->7
Consume->7
Produced->8
Consume->8
Produced->9
Consume->9

Thread Local Example

A simple example for Thread Local concept in Java:

public
class ThreadLocalExamples {
public static int x =0;
private static ThreadLocal<Integer> tlocal;
public static void main(String[] args) {
tlocal = new ThreadLocal<Integer>();
ThreadLocalExamples tl =
new ThreadLocalExamples();
T1 t1 = tl.
new T1();
t1.start();
T2 t2 = tl.
new T2();
t2.start();
tlocal.set(100);
System.
out.println("main thread->"+tlocal.get());
try {
t1.join();
t2.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.
out.println(x);
}
class T1 extends Thread {
@Override
public void run() {
x++;
System.
out.println("value in t1->"+tlocal.get());
tlocal.set(200);
System.
out.println("value in t1->"+tlocal.get());
}
}
class T2 extends Thread {
@Override
public void run() {
x++;
System.
out.println("value in t2->"+ tlocal.get());
tlocal.set(300);
}
}
}

 Output:
main thread->100
value in t1->null
value in t1->200
value in t2->null
2

Reverse of single linked list

Reverse a single linked list:

public void reverse()
{
   Node currentNode, nextNode, loopNode;
   if(first==null)
      return;

   currentNode=first;
   nextNode= first.next;
   loopNode=null;


   while(nextNode != null)
   {
        currentNode.next = loopNode;
        loopNode= currentNode;
        currentNode=nextNode;
        nextNode =nextNode.next;
   }

   first = currentNode;
   first.next = loopNode;

}

Dead lock using threads

public class Deadlock {
  public static void main(String[] args) {
    // These are the two resource objects we'll try to get locks for
    final Object resource1 = "resource1";
    final Object resource2 = "resource2";
    // Here's the first thread.  It tries to lock resource1 then resource2
    Thread t1 = new Thread() {
      public void run() {
        // Lock resource 1
        synchronized(resource1) {
          System.out.println("Thread 1: locked resource 1");

          // Pause for a bit, simulating some file I/O or something. 
          // Basically, we just want to give the other thread a chance to
          // run.  Threads and deadlock are asynchronous things, but we're
          // trying to force deadlock to happen here...
          try { Thread.sleep(50); } catch (InterruptedException e) {}

          // Now wait 'till we can get a lock on resource 2
          synchronized(resource2) {
            System.out.println("Thread 1: locked resource 2");
          }
        }
      }
    };

    // Here's the second thread.  It tries to lock resource2 then resource1
    Thread t2 = new Thread() {
      public void run() {
        // This thread locks resource 2 right away
        synchronized(resource2) {
          System.out.println("Thread 2: locked resource 2");

          // Then it pauses, for the same reason as the first thread does
          try { Thread.sleep(50); } catch (InterruptedException e) {}

          // Then it tries to lock resource1.  But wait!  Thread 1 locked
          // resource1, and won't release it 'till it gets a lock on
          // resource2.  This thread holds the lock on resource2, and won't
          // release it 'till it gets resource1.  We're at an impasse. Neither
          // thread can run, and the program freezes up.
          synchronized(resource1) {
            System.out.println("Thread 2: locked resource 1");
          }
        }
      }
    };

    // Start the two threads. If all goes as planned, deadlock will occur,
    // and the program will never exit.
    t1.start();
    t2.start();
  }
}

This is from examples.oreilly.com....