Monday, October 11, 2010

Solving Leader Election Problem in a Clustered enviroment with JGroups

First of all this blog entry is written for jgroups 2.5.1 and  now jgroups.3-0-1-final is available and example is rewritten by me.

It is remommended to use new api. Because DistributedLock class is deprecated. Have a look at the new blog entry . 

Let me jump in the source code again without any amateur explaination about Leader Election Problem.

Scenario : There will be three competitor in our cluster. First one will be the master (~leader) because there is no other one currently.

Second and Third One(s) won't have a chance to get "Distributed Lock". After a while our master will be killed by us with a big pleasure :)

Then we will see new MASTER(~leader of our cluster).You can see the message on  snapshots below.

import org.jgroups.*;
import org.jgroups.blocks.DistributedLockManager;
import org.jgroups.blocks.VotingAdapter;
import org.jgroups.blocks.NotificationBus;
import org.jgroups.blocks.LockNotGrantedException;

import java.io.Serializable;

public class TheOne extends ReceiverAdapter {

    private JChannel channel;
    private volatile boolean becomeMaster;
    private DistributedLockManager lockManager;
    private VotingAdapter adapter;

    public static void main(String[] args) throws Exception {
        System.setProperty("jgroups.bind_addr", "10.34.34.137");//use your ip address
        TheOne master = new TheOne();
        master.start();
    }


    public void start() throws ChannelException {
        channel = new JChannel("udp.xml");
        adapter = new VotingAdapter(channel);
        adapter.addMembershipListener(this);
        lockManager = new DistributedLockManager(adapter, "DistributedLockManager");
        channel.connect("ClassPresidentCluster");
    }


    public void viewAccepted(final View new_view) {
        new Thread() {
            public void run() {
                System.out.println("new view " + new_view);
                getLock();
            }
        }.start();
    }


    private void getLock() {
        if (becomeMaster) {
            System.out.println("-- STILL I am the ONE !!");
            return;
        }
        try {
            System.out.println("looking for lock");
            System.out.println(lockManager);
            System.out.println(adapter);
            lockManager.lock("writer", channel.getAddress(), 0);
            becomeMaster = true;
            System.out.println(" -- I AM THE ONE !!!");
        } catch (ChannelException e) {
            e.printStackTrace();
        } catch (LockNotGrantedException e) {
            System.out.println("no lock for me :(");
        }
    }
}


1)First competitor comes to area a becomes a master very easily.

2)Second competitor comes to area but lock is owned by the first one.

3)Third competitor comes to area but lock is owned by the first one still.


4)After killing the master second one becomes a MASTER.



Example for java.util.concurrent.locks.ReentrantReadWriteLock usage


Let's try the latest sample with another beauty of the java.util.concurrent package :ReentrantReadWriteLock



import java.util.concurrent.locks.*;

public class ReentrantReadWriteLockExample {
    int i = 0;

    public static void main (String[] args) {
        final ReentrantReadWriteLockExample example = new ReentrantReadWriteLockExample();
        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

        final Runnable r = new Runnable () {
            public void run () {
                while (true) {
                    try {
                        lock.writeLock().lock();
                        //Here is the critical section jobs are being done securely..
                        example.printSomething ();
                        Thread.sleep (1000);
                        lock.writeLock().unlock();
                    } catch (Exception ex) {
                        System.out.println (" -- Interrupted...");
                        ex.printStackTrace ();
                    }
                }
            }
        };

        new Thread (r).start ();
        new Thread (r).start ();
        new Thread (r).start ();
    }

    public void printSomething (){
        i++;
        System.out.println (" -- current value of the i :"+ i);
    }
}

Thursday, October 7, 2010

Example for java.util.concurrent.Semaphore usage

Let's try to increment a simple integer variable without any synchronization.
See what happens if we don't care about critical sections :)


Yes even we are not able to increment an integer without using any synchronization primitives.So we see the values of "i" 10-11-10 which are highlighted in the messages pane of my ide.

And...Here is the succesfull result in which we are using a Semaphore from java 1.5 (Tiger).

import java.util.concurrent.locks.*;
import java.util.concurrent.Semaphore;

public class SemaphoreExample {
    int i = 0;

    public static void main (String[] args) {
        final SemaphoreExample example = new SemaphoreExample();
        final Semaphore semaphore = new Semaphore (1);

        final Runnable r = new Runnable () {
            public void run () {
                while (true) {
                    try {
                        semaphore.acquire();
                        example.printSomething ();
                        Thread.sleep (1000);
                        semaphore.release();
                    } catch (Exception ex) {
                        System.out.println (" -- Interrupted...");
                        ex.printStackTrace ();
                    }
                }
            }
        };

        new Thread (r).start ();
        new Thread (r).start ();
        new Thread (r).start ();
    }

    public void printSomething (){
        i++;
        System.out.println (" -- current value of the i :"+ i);
    }
}
 

Monday, September 27, 2010

Take a trip into Java Monitor with your source code






                      line 1:  synchronized(obj){//Entry Set
                      line 2:       System.out.println ("I am the master of monitor");//Owner
                      line 3:       obj.wait();//Wait Set
                                 }
                      line 4:           //Out of the monitor

More than one thread can be blocked/found on line 1 , line 3 and line 4 at the same time, but there can only be one active thread at the same time at line 2 as a monitor owner.

You may want to check this sample also : http://javabender.blogspot.com/2010/09/example-for-understanding-javas-wait.html

Thursday, September 23, 2010

Example for Understanding Java's Wait / Notify Mechanism and Synchronization

 public class WaitNotifyExample {

    public static void main (String[] args) {
        final Object obj = new Object();

        Runnable r = new Runnable () {
            public void run () {
                while (true) {
                    try {
                        System.out.println ("-- this lines are being printed in another thread.." + Thread.currentThread ().getName ());
                        synchronized(obj){// The current thread must own this object's monitor see javadoc guys..Object.wait ();
                            obj.wait();// just wait for somebody else to awake you here.
                        }
                    } catch (Exception ex) {
                        System.out.println (" -- Interrupted...");
                        ex.printStackTrace ();
                    }
                }
            }
        };

        new Thread (r).start ();//we crated and started a lazy guy here
        new Thread (r).start ();//another lazy guy
        new Thread (r).start ();//this can be me :)

        while (true) {
            System.out.println (" -- this lines are bing printed in main thread.." + Thread.currentThread ().getName ());
            try {

                Thread.currentThread ().sleep (5000);//Our master will sleep for 5 seconds
                synchronized(obj){//same reason with above synchronized
                    obj.notifyAll();// Then it will say others wake up !
                }
                Thread.currentThread ().sleep (500);//If we don'T stop the main thread here it will be the owner of the monitor of obj object always.
                                                    //It is in a while loop.Others will be blocked on synchronized statement.

            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}



---| Lets look at to the system out , I have took a thread dump for u also  |-----
-- this lines are being printed in another thread..Thread-0
-- this lines are being printed in another thread..Thread-1
 -- this lines are bing printed in main thread..main
-- this lines are being printed in another thread..Thread-2
-- this lines are being printed in another thread..Thread-0
-- this lines are being printed in another thread..Thread-1
 -- this lines are bing printed in main thread..main
-- this lines are being printed in another thread..Thread-2
-- this lines are being printed in another thread..Thread-0
-- this lines are being printed in another thread..Thread-1
Full thread dump Java HotSpot(TM) Server VM (1.5.0_08-b03 mixed mode):

"Thread-2" prio=1 tid=0x09dcaa88 nid=0xfa6 in Object.wait() [0x6e8cb000..0x6e8cc080]
    at java.lang.Object.wait(Native Method)
    - waiting on <0xaa00e258> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:474)
    at sil.WaitNotifyExample$1.run(WaitNotifyExample.java:17)//
obj.wait()
    - locked <0xaa00e258> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:595)

"Thread-1" prio=1 tid=0x09dc9218 nid=0xfa5 in Object.wait() [0x6e94c000..0x6e94d100]
    at java.lang.Object.wait(Native Method)
    - waiting on <0xaa00e258> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:474)
    at sil.WaitNotifyExample$1.run(WaitNotifyExample.java:17)//
obj.wait()
    - locked <0xaa00e258> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:595)

"Thread-0" prio=1 tid=0x09dcb550 nid=0xfa4 in Object.wait() [0x6e9cd000..0x6e9cdd80]
    at java.lang.Object.wait(Native Method)
    - waiting on <0xaa00e258> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:474)
    at sil.WaitNotifyExample$1.run(WaitNotifyExample.java:17)//
obj.wait()
    - locked <0xaa00e258> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:595)

"main" prio=1 tid=0x09cecee0 nid=0xf94 waiting on condition [0xbfe77000..0xbfe776f8]
    at java.lang.Thread.sleep(Native Method)
    at sil.WaitNotifyExample.main(WaitNotifyExample.java:37)//
Thread.currentThread ().sleep (500)