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



*/

java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1 ORA-01882: timezone region not found

ava.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:457)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:397)
=====================================================

Soln: This issue mainly appears in Mac or Linux systems when making JDBC connection. To fix this follow below
settings.

To run a single java class

(1) in eclipse go run – > run configuration
(2) in there go to JRE tab in right side panels
(3) in VM Arguments section paste this
(4) -Duser.timezone=GMT
(5) then Apply – > Run

To run a Project in which a java class is doing jdbc connection :

Update vm arguments of project under ( run configuration section ) with -Duser.timezone=”GMT”

below is updated VM arguments list

-Dcatalina.base=”/Users/STS_Work/.metadata/.plugins/org.eclipse.wst.server.core/tmp0″ -Dcatalina.home=”/Users/mySoftInst/apache-tomcat-7.0.54″ -Dwtp.deploy=”/Users/STS_Work/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps” -Djava.endorsed.dirs=”/Users/mySoftInst/apache-tomcat-7.0.54/endorsed” -Duser.timezone=”GMT”

A Practical scenario for using volatile in java

working example of “volatile” for Java7+ is a highly used searching keyword
for java guys. After lots of search people hardly get any working and effective
code on Volatile. So I decided to put one sample code here on Volatile.

A short note on volatile #
Volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache value of this variable and always read it from main memory. Java guarantees that value of volatile variable will always be read from main memory and not from Thread’s local cache.So if you want to share any variable in which read and write operation is atomic by implementation e.g. read and write in int or boolean variable you can declare them as volatile variable. This guarantees visibility of changes made by one thread to another thread also.Java volatile keyword cannot be used with method or class
and it can only be used with variable. Java volatile keyword also guarantees visibility and ordering , after Java 5 write to any volatile variable happens before any read into volatile variable. By the way use of volatile keyword also prevents compiler or JVM from reordering of code or moving away them from synchronization barrier.

Below is one example based on volatile, in which different Threads will try to search a number is different range if any thread finds the number search operation will be stopped by all Threads.

 public class SerachUsingVolatile {

	// search range starts with
	static int START = 0;
	static int END = 10000;

	public static void main(String[] args) {

		NumberFinder t = new NumberFinder(28000);

		Thread t1 = new Thread(t, "T1");
		Thread t2 = new Thread(t, "T2");
		Thread t3 = new Thread(t, "T3");

		t1.start();
		t3.start();

		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		t2.start();

	}

}

class NumberFinder implements Runnable {
	//volatile boolean keepRunning = true;
        boolean keepRunning = true;
	int numToFind;

	NumberFinder(int nf) {
		this.numToFind = nf;
	}

	public void run() {

		int start = SerachUsingVolatile.START;
		int end = SerachUsingVolatile.END;

		// move range of search for each Thread
		SerachUsingVolatile.START = SerachUsingVolatile.START + 10000;
		SerachUsingVolatile.END = SerachUsingVolatile.END + 10000;

		while (keepRunning) {

			for (int i = start; i <= end; i++) {
				if (i == numToFind) {
					keepRunning = false;
					System.out.println("Target found by Thread: " + Thread.currentThread().getName()
							+ " rest all Threads should stop searching !!! ");
				}
			}
		}
		System.out.println(" Search stopped for Thread :" + Thread.currentThread().getName());
	}
}

**************************************************
Output with volatile :

Search stopped for Thread :T1
Target found by Thread: T2 rest all Threads should stop searching !!!
Search stopped for Thread :T3
Search stopped for Thread :T2

Output without volatile :

Target found by Thread: T2 rest all Threads should stop searching !!!
Search stopped for Thread :T2

*************************************************

That’s all Guys !!!! I am open for your questions n comment 🙂