Search code examples
multithreadingproducer-consumerthread-synchronization

Thread synchronization with multiple objects


I have been facing this problem for many days, Please help me out. I am implementing producer-consumer example using thread synchronization. I have made some twist in this traditional program. Instead of using only one queue object, i have used two Queue objects. But program is not working.. (PS- I know i can make this program work by using only one object of queue, But what if i want to use two queue objects ?? )

class Queue {

static int value;

static boolean valueSet = false;

public static final Object obj;

static {

    obj = new Object();
}


void push() {

    synchronized(Queue.obj) {

        while( Queue.valueSet ) {

            try {
            Thread.sleep(1000);
            }catch(Exception e) {}
        }

        System.out.print("\n\n Push:-  " + (++(Queue.value)));
        Queue.valueSet = true;

        return;

    }

}

void pop() {

    synchronized(Queue.obj) {

        while(!(Queue.valueSet)) {

            try {
            Thread.sleep(1000);
            }catch(Exception e) {}
        }

        System.out.print("\n\n Pop:-   " + Queue.value);

        Queue.valueSet = false;

        return;

    }

}

}

class Producer implements Runnable {

Queue Q;
Thread P;


Producer(Queue Q) {

    this.Q = Q;
    P = new Thread(this);
    P.start();

}

public void run() {

    while(true) {

        Q.push();

    }
}

}

class Consumer implements Runnable {

Queue Q;
Thread C;

Consumer(Queue Q) {

    this.Q = Q;
    C = new Thread(this);
    C.start();


}

public void run() {

    while(true) {

        Q.pop();

    }
}

}

public class TestQueue {

public static void main(String[] args) {

    Queue Q1 = new Queue();
    Queue Q2 = new Queue();

    Object obj = new Object();


    Producer p = new Producer(Q1);
    Consumer c = new Consumer(Q2);
}

}


Solution

  • I got the answer. My misconception was wait,notify and notifyall methods are of thread class. So i was invoking them on thread object.

    Solution is to just invoke wait and notify method on shared static object other than thread.

    Answer:-

    class Queue {

    static int value;
    
    static boolean valueSet = false;
    
    public static final Object obj;
    
    static {
    
        obj = new Object();
    }
    
    
    void push() {
    
        synchronized(Queue.obj) {
    
            while( Queue.valueSet ) {
    
                try {
                Queue.obj.wait();
                Thread.sleep(1000);
                }catch(Exception e) {
    
                    e.printStackTrace();
                }
            }
    
            System.out.print("\n\n Push:-  " + (++(Queue.value)));
            Queue.valueSet = true;
            Queue.obj.notify();
        }
    
    }
    
    void pop() {
    
        synchronized(Queue.obj) {
    
            while(!(Queue.valueSet)) {
    
                try {
                Queue.obj.wait();
                    Thread.sleep(1000);
                }catch(Exception e) {
    
                    e.printStackTrace();
                }
            }
    
            System.out.print("\n\n Pop:-   " + Queue.value);
    
            Queue.valueSet = false;
            Queue.obj.notify();
        }
    
    }
    

    }

    class Producer implements Runnable {

    Queue Q;
    Thread P;
    
    
    Producer(Queue Q) {
    
        this.Q = Q;
        P = new Thread(this);
        P.start();
    
    }
    
    public void run() {
    
        while(true) {
    
            Q.push();
    
        }
    }
    

    }

    class Consumer implements Runnable {

    Queue Q;
    Thread C;
    
    Consumer(Queue Q) {
    
        this.Q = Q;
        C = new Thread(this);
        C.start();
    
    
    }
    
    public void run() {
    
        while(true) {
    
            Q.pop();
    
        }
    }
    

    }

    public class TestQueue {

    public static void main(String[] args) {
    
        Queue Q1 = new Queue();
        Queue Q2 = new Queue();
    
        Producer p = new Producer(Q1);
        Consumer c = new Consumer(Q2);
    }
    

    }