One producer and multiple consumers wherein the producer has to wait until all consumers finish before adding more data I am trying to solve the scenario involving 1 producer and 5 consumers. The producer puts data to queue and waits till all consumers have finished before adding more data.

Please review and let me know if there is room for improvement.

import java.util.LinkedList;
import java.util.Queue;

public class ReadUpdate {

   static int cntr;
   static volatile int writeLck = 1;
   static int numSupplied;
   Queue queue = new LinkedList&lt;Node&gt;();

    public static void main(String arg[]) {
        ReadUpdate rU = new ReadUpdate();
        Producer p = new Producer(rU.queue);
        p.start();
        Consumer c1 = new Consumer(rU.queue, 1);
        c1.setName("1");
        c1.start();
        Consumer c2 = new Consumer(rU.queue, 2);
        c2.setName("2");
        c2.start();
        Consumer c3 = new Consumer(rU.queue, 3);
        c3.setName("3");
        c3.start();
        Consumer c4 = new Consumer(rU.queue, 4);
        c4.setName("4");
        c4.start();
        Consumer c5 = new Consumer(rU.queue, 0);
        c5.setName("5");
        c5.start();
    }
 }

class Consumer extends Thread {
    Queue queue;
    int turn;

    Consumer(Queue queue, int turn) {
        this.queue = queue;
        this.turn = turn;
    }

    public void run() {
        while (ReadUpdate.numSupplied &lt;= 100) {
            synchronized (ReadUpdate.class) {
                while (queue.isEmpty() || ReadUpdate.cntr % 5 != this.turn) {
                    try {
                        ReadUpdate.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("THREAD " + Thread.currentThread().getName()
                        + " GOT " + queue.poll());
                if (ReadUpdate.cntr % 5 == 0) {
                    ReadUpdate.writeLck = 1;
                } else {
                    ReadUpdate.cntr++;
                }
                ReadUpdate.class.notifyAll();
            }
        }
    }
}

class Producer extends Thread {
    Queue queue;

    Producer(Queue queue) {
        this.queue = queue;
        ReadUpdate.numSupplied++;
    }

    public void run() {
        while (ReadUpdate.numSupplied &lt; 100) {
            synchronized (ReadUpdate.class) {
                while (ReadUpdate.writeLck == 0) {
                    try {
                        ReadUpdate.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int i = 0; i &lt; 5; i++) {
                    queue.offer(ReadUpdate.numSupplied++);
                }
                ReadUpdate.writeLck = 0;
                ReadUpdate.cntr++;
                ReadUpdate.class.notifyAll();
            }
        }
    }
}
It's not recommended to inherit from Thread. Instead implement Runnable and pass it to a new Thread which you store in a member and provide accesses for what you need. This also lets you pass a ThreadFactory for some customization options for the threads used.

class Producer extends Runnable{

    private Thread thr;

    Producer(Queue queue, ThreadFactory fact) {
        if(fact == null)
            thr = new Thread(this, "producer thread");
        else
            thr = fact.newThread(this);
        //...
    }

    public void start(){
        thr.start();
    }

    //...
}


As for synchronizing if you only needed the consumers to run once you could have used a CountDownLatch but that cannot be reset. So you'll have to use a CyclicBarrier. 

With a cyclic barrier you can make the producer the Runnable that gets invoked when the last thread calls its await. Then you can be sure all but one consumer threads are waiting for the producer code to finish.