Safe Singleton for your multi-core servers

Purpose of a Singleton is to have one copy of an object in JVM. But writing below code without volatile in a multi core environment may result in multiple copies of Singleton if any failover occurs.
In a multi-core server multiple Threads of your code may try to create a Singleton object. If singleton variable ( _instance ) is properly not visible to all Threads in all running conditions then Singleton will appear with multiple copies ( which is never expected ).To avoid such cases _instance variable should be declared volatile to make sure if a Thread is creating Singleton instance and just after creation it lost the CPU, all other threads should be communicated that _instance is not null now.

public class Singleton{

private static volatile Singleton _instance;
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null)
_instance = new Singleton();
}
}
return _instance;
} 

Sample code for Producer n Consumer Problem

There are at least 5 direct ways to write a Producer n Consumer Problem. The basic is one which use wait() and notify().

// Queue
class CustomerQueue
{

    String sharedCustomerQueue[] = new String[5];
}

// Client
public class ProducerConsumerQ
{

    static int NEED_TO_SERVE_BATCH = 2;

    public static void main(String[] args)
    {

        System.out.println(" Producer will fill SharedQueue with 5 elements in each batch.");
        System.out.println(" Consumer will consume elements available in SharedQueue in each batch.");

        System.out.println(" Total " + NEED_TO_SERVE_BATCH + " will be served.");
        System.out.println(" \n ***************************************************************************** ");
        CustomerQueue cq = new CustomerQueue();
        Thread pro = new producer(cq);
        Thread con = new consumer(cq);
        pro.setName("Producer");
        con.setName("Consumer");
        pro.start();
        con.start();

    }

}

class producer extends Thread
{

    int count = 0;
    CustomerQueue qp;

    public producer(CustomerQueue q)
    {
        qp = q;
    }

    @Override
    public void run()
    {

        while (count < ProducerConsumerQ.NEED_TO_SERVE_BATCH)
        {
            System.out.println("\n");
            synchronized (qp.sharedCustomerQueue)
            {

                // everytime generate 5 random numbers and put in Queue
                for (int p = 0; p < 5; p++)
                {
                    qp.sharedCustomerQueue[p] = (int) ((Math.random() * 10) % 10) + "";
                    System.out.println("Producer : Genereated item is :" + qp.sharedCustomerQueue[p]);
                }
                qp.sharedCustomerQueue.notify();
                try
                {
                    qp.sharedCustomerQueue.wait();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                count++;
            }
        }

    }
}

class consumer extends Thread
{

    int count = 0;
    CustomerQueue qc;

    public consumer(CustomerQueue q)
    {
        qc = q;
    }

    @Override
    public void run()
    {

        while (count < ProducerConsumerQ.NEED_TO_SERVE_BATCH)
        {
            if (qc.sharedCustomerQueue[0] != null) // consume only if queue is filled
            {
                synchronized (qc.sharedCustomerQueue)
                {

                    for (String qItem : qc.sharedCustomerQueue)
                    {
                        System.out.println("Consumer : Consuming item " + qItem);
                    }

                    System.out.println("\n");
                    qc.sharedCustomerQueue.notify();

                    try
                    {
                        qc.sharedCustomerQueue.wait();
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        }

    }
}

/*
 Producer will fill SharedQueue with 5 elements in each batch.
 Consumer will consume elements available in SharedQueue in each batch.
 Total 2 will be served.
 
 ***************************************************************************** 
Producer : Genereated item is :3
Producer : Genereated item is :5
Producer : Genereated item is :5
Producer : Genereated item is :1
Producer : Genereated item is :1
Consumer : Consuming item 3
Consumer : Consuming item 5
Consumer : Consuming item 5
Consumer : Consuming item 1
Consumer : Consuming item 1




Producer : Genereated item is :9
Producer : Genereated item is :5
Producer : Genereated item is :8
Producer : Genereated item is :9
Producer : Genereated item is :8
Consumer : Consuming item 9
Consumer : Consuming item 5
Consumer : Consuming item 8
Consumer : Consuming item 9
Consumer : Consuming item 8



*/