Вопрос

I am trying to write a simple producer consumer program , using one Stack, one producer and multiple consumers ,

As you can see in the following code , I have one PC class which starts the threads. The problem is that in the result I only see one consumer popping off the stack. Why does this happen ? Why doesn't it let other consumers to pop off the stack too ?

class PC{
    static Stack<Integer> sharedStack = new Stack<Integer>();
    final static int MAX_SIZE = 10;
    public static void main(String[] args){
        new PC();
    }
    public PC(){
        new Thread(new Producer() , "Producer").start();
        Consumer consumer = new Consumer();
        for (int i = 1 ; i < 10 ; i++)
            new Thread(consumer , "Consumer " + i).start();
    }
    class Producer implements Runnable{
        Random rnd = new Random();
        public void run() {
            while(true){
                synchronized (sharedStack) {
                    if (sharedStack.size() < MAX_SIZE){
                        int r = rnd.nextInt(1000);
                        System.out.println(Thread.currentThread().getName() + " produced :" + r);
                        sharedStack.push(r);
                        sharedStack.notifyAll();
                    }                   
                }
            }
        }
    }
    class Consumer implements Runnable{
        public void run() {
            while (true){
                synchronized(sharedStack){
                    if (sharedStack.isEmpty()){
                        try {
                            sharedStack.wait();
                        } catch (InterruptedException e) {e.printStackTrace();}
                    }
                    System.out.println(Thread.currentThread().getName() + " consumed :" + sharedStack.pop());                   
                }
            }
        }
    }
}
Это было полезно?

Решение

the problem is that you do synchronization on stack instance in your recievers, so no matter how many you have only one would process at time. So no need to have more than one reciever than :)

First, you should probably change your algorithm to get rid of synchronization in place.

I'd just google for producer with multiple consumers in java and get some inspiration depending on your preferences.

UPDATE:

You just say in your consumer:

 Consumer implements Runnable{
        public void run() {
            while (true){
                synchronized(sharedStack){

that means, only the 1.st consumer comming to the statement synchronized(sharedStack){ will be able to get in, others will wait till the one leaves the bloc }.

So that means you process only by one consumer in time. Others wait and the 1.st lucky one will process next iteration (in your case was it the same one who processed the iteration before).

See the official docs for more info on synchronized blocks.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top