Friday, August 28, 2009

Deadlock Example in Java

Deadlock is situation where two or more thread are blocked and waiting for each other.

Consider example that there are two threads running. Thread1 and Thread2. Thread1 puts lock on object1 and goes to sleep.Consider that when thread 1 puts lock on object1 after it goes to sleep, it tries to put lock on object2. 

When Thread 1 goes to sleeps,Thread 2 is up and running. it puts lock on object2. and thread 2 goes to sleep. and try to put lock on object1. but since object 1 is locked by Thread 1 and only will be released when thread 1 gets lock on object2. But Thread 2 already has locked on object2 and will be only released when it get locks on object1. This is Deadlock :) ha ha.

If you are using netbeans then you can get Thread Dump using netbeans Wiki.

Java Program to demostrate Deadlock Situation :


package com.anuj.basic;

import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Anuj Patel
 */
public class DeadLockDemostration {

    public void showDeadLock() {
        final Object object1 = new Object();
        final Object object2 = new Object();

        Thread thread1 = new Thread(new Runnable() {

            @Override
            public void run() {
                synchronized (object1) {
                    System.out.println("Thread1 acquired lock on object1");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(DeadLockDemostration.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    synchronized (object2) {
                        System.out.println("Thread1 acquired lock on object2");
                    }
                }

            }
        });
        thread1.start();

        Thread thread2 = new Thread(new Runnable() {

            @Override
            public void run() {
                synchronized (object2) {
                    System.out.println("Thread2 acquired lock on object2");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException ex) {                         Logger.getLogger(DeadLockDemostration.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    synchronized (object1) {
                        System.out.println("Thread2 acquired lock on object1");
                    }
                }
            }
        });
        thread2.start();
    }

    /**
    * Check weather deadlock occur or not
    */
    public void detectDeadlock() {
        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        long[] threadIds = threadBean.findMonitorDeadlockedThreads();

        if (threadIds != null) {
            System.out.println("Number of deadlocked threads : " + threadIds.length);
            ThreadInfo[] infos = threadBean.getThreadInfo(threadIds);

            for (ThreadInfo info : infos) {
                displayThreadInfo(info);
            }
        } else {
            System.out.println("Number of deadlocked threads : 0" + 0);
        }
    }

   /**
   * Display threadInformation
   */  
    private void displayThreadInfo(ThreadInfo threadInfo) {
        // print thread
        printThread(threadInfo);

        // print stack trace with locks
        StackTraceElement[] stacktrace = threadInfo.getStackTrace();

        //get Locked Monitors
        MonitorInfo[] monitors = threadInfo.getLockedMonitors();

        for (int i = 0; i < stacktrace.length; i++) {
            StackTraceElement stackTraceElement = stacktrace[i];
            System.out.println("at " + stackTraceElement.toString());
            for (MonitorInfo monitorInfo : monitors) {
                if (monitorInfo.getLockedStackDepth() == i) {
                    System.out.println(" locked " + monitorInfo);
                }
            }
        }
    }

    /**
    * Print Thread 
    */
    private void printThread(ThreadInfo ti) {
        System.out.println("Thread : " + ti.getThreadName());
        System.out.println("Thread Id : " + ti.getThreadId());
        System.out.println("Thread Status : " + ti.getThreadState());
        System.out.println("Thread locked on : " + ti.getLockName());
        System.out.println("Thread isSuspended : " + ti.isSuspended());
        System.out.println("Thread isInNative : " + ti.isInNative());
        System.out.println("Thread LockOwnerName : " + ti.getLockOwnerName());
        System.out.println("Thread LockOwner Id : " + ti.getLockOwnerId());
    }

    public static void main(String[] args) {
        DeadLockDemostration deadLockDemostration = new DeadLockDemostration();
        deadLockDemostration.showDeadLock();

        try {
            //execute detectDeadlock method after both thread run
            Thread.sleep(100);
            deadLockDemostration.detectDeadlock();
        } catch (InterruptedException ex) {
            Logger.getLogger(DeadLockDemostration.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
Output :
run:
Thread1 acquired lock on object1
Thread2 acquired lock on object2
Number of deadlocked threads: 2
Programatically you can check wheather there is deadlock or not using few lines of code as :
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
long[] threadIds = threadBean.findMonitorDeadlockedThreads();
int deadlockedThreads = threadIds != null ? threadIds.length : 0;
System.out.println("Number of deadlocked threads: " + deadlockedThreads);
Author : Anuj Patel Blog : http://goldenpackagebyanuj.blogspot.in/

No comments:

Post a Comment