Java线程生产者消费者算法无法正常工作

时间:2011-05-30 13:59:42

标签: java multithreading concurrency producer-consumer producer

我正在尝试学习线程,因此我写了一个样本生产者消费者问题,其中生产者产生1到10的数字,消费者必须显示它们。但只有消费者显示数字1并停止。

正如我所说,程序写得不好而且可能很荒谬,但我仍然想弄清楚为什么所有从1到10的数字都不打印的原因,因为我会在编码而不是从例子中记得最佳。< / p>

我正在使用两个varibales跟踪Producres或consumer活动的完成情况,以便我可以执行另一个。

/ getStatus(消费者C) 传递消费者参考,以便生产者得到消费者的反对..并且它可以用来了解消费者的状态..它... /

import java.lang.Math;
public class Hello{

public static void main(String args[]) {

    System.out.println("---1");
    new Consumer().start();

}

}

class Producer extends Thread{

public int produce = 0;
public Consumer consumerObj =null;
int count = 1;
boolean producerStatus = false;

public void run(){

    System.out.println("---4");
    synchronized(this){

        do{

            System.out.println("---6");
            produce = produce+1;
            producerStatus = true;
            notify();
            consumerObj.consumerStatus = false;
            System.out.println("---9");
            count = count+1;

        }while(count<=10 && consumerObj.getStatus());

    }

}

public int getItem(){
    return produce;
}



public boolean getStatus(Consumer c){
    consumerObj = c;
    return producerStatus;

}

}

class Consumer extends Thread{

boolean consumerStatus = false;
int count =0;
public void run(){

    System.out.println("---2");
    Producer p = new Producer();
    p.getStatus(this);
    p.start();
    try{
        System.out.println("---3");
        synchronized(p){
            System.out.println("---5");
            p.wait();

            System.out.println("---8");
        }
    }
    catch(Exception e){
            System.out.println("exception");
    }

    synchronized(p){
        try{
            while(p.getStatus(this) && count<=9 ){

                System.out.println("---7");
                int consume = p.getItem();
                System.out.println("the produced item is ----->"+consume);
                count = count+1;
                p.producerStatus  = false;
                consumerStatus = true;
                p.wait();                   
                System.out.println("---10");

            }
        }
        catch(Exception e){
            System.out.println("exception");
        }

    }

}

public boolean getStatus(){

    return consumerStatus;

}
}

输出:

---1
---2
---3
---5
---4
---6
---9
---8
---7
the produced item is ----->1
---10

来自... Suraj的输入..现在该程序工作正常..见下文..

import java.lang.Math; 公共类Hello {

public static void main(String args[]) {

    System.out.println("---1");
    new Consumer().start();

}

}

class Producer extends Thread{

public int produce = 0;
public Consumer consumerObj =null;
int count = 1;
boolean producerStatus = false;

public void run(){

    System.out.println("---4");

        do{
            if(consumerObj.getStatus()){


            System.out.println("---6");
            produce = produce+1;
            System.out.println("---9 -- >produce is -->"+produce);
            producerStatus = true;
            synchronized(this){

            notify();
            System.out.println("---6.111");
            }

            consumerObj.consumerStatus = false;
            count = count+1;


            }


        }while(count<=10);


}

public int getItem(){

    return produce;

}

public boolean getStatus(Consumer c){

    consumerObj = c;
    return producerStatus;

}

}



class Consumer extends Thread{

boolean consumerStatus = true;
int count =1;
public void run(){

    System.out.println("---2");
    Producer p = new Producer();
    p.getStatus(this);
    p.start();//can a thread1 wait on an thread2 before the thread2 hass tarted and in this case wll notify on the scnd thread reaally notify therad1 ..
    try{
        System.out.println("---3");
        synchronized(p){
            System.out.println("---5");
            p.wait();

            System.out.println("---8");
        }
    }
    catch(Exception e){
            System.out.println("exception");
    }


        try{
            while(count<=10 ){

                System.out.println("---7");
                int consume = p.getItem();
                System.out.println("the produced item is ----->"+consume);
                count = count+1;
                p.producerStatus  = false;
                consumerStatus = true;
                synchronized(p){
                p.wait();   
                System.out.println("---10");        
                }


            }
        }
        catch(Exception e){
            System.out.println("exception");
        }


}

public boolean getStatus(){

    return consumerStatus;

}

}

3 个答案:

答案 0 :(得分:3)

行。 该计划是错误的。

  1. 消费者线程来了,等待锁定。
  2. 生产者循环中的第一次迭代将调用notify但是doesent释放锁定,因为while循环在synchronized块内。它将迭代10次而不释放锁定,并最终连续10次呼叫通知。
  3. 但消费者只会被唤醒一次,消费者第二次调用wait()它会一直等待,因为现在没有人可以调用通知(因为生产者的所有10次迭代都已结束)
  4. 所以问题是消费者线程正在流氓但是没有人通知它,因为制作人在一次拍摄中完成了所有10次迭代。

答案 1 :(得分:0)

在Producer中,您设置

consumerObj.consumerStatus = false;

并立即在循环条件中检查此值。循环在1个循环后结束。 之后

count = count+1;

你应该等待(“消费”)。

try{
    this.wait();
} catch (Exception e) {
    e.printStackTrace();
}

消费者中的同样问题。循环中的最后一件事应该是

p.wait();

答案 2 :(得分:0)

你应该使用BlockingQueues。 见http://www.javamex.com/tutorials/synchronization_producer_consumer_2.shtml

上述实施方案效率低下,迫使所有商家阻止。 有多个队列,您可以阻止所有消费者阻止。 你可以在谷歌上找到例子。 Java.util.concurrent使用它,这是有原因的。