Java线程生产者使用者算法无法正常工作

问题描述

| 我试图学习线程,因此写了一个示例生产者消费者问题,其中生产者产生1到10之间的数字,而消费者必须显示它们。但是只有消费者显示数字1并停止。 正如我所说的,该程序编写得不好,可能很荒谬,但我仍然想弄清楚为什么从1到10的所有数字都没有打印出来的原因,因为我会在编写代码时而不是从示例中记住这一点。 我使用两个变量来跟踪产品或消费者活动的完成,以便我可以执行另一个。 / 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 ..输入之后,现在程序可以正常工作..参见下文.. 导入java.lang.Math; 公开课您好{
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;

}

}
    

解决方法

        好。 程序错误。 使用者线程到来并等待锁定。 生产者循环中的第一个迭代将调用notify,但由于while循环位于同步块内部,因此并没有释放锁。它会反复进行10次而不释放锁,并最终连续10次调用通知。 但是,消费者只需要唤醒一次,而消费者第二次调用wait()时,它将保持等待状态,因为现在没有人可以调用notify(因为Producer的所有10次迭代都结束了) 因此,问题在于消费者线程正在消耗,但是没有人通知它,因为生产者以1张镜头完成了所有10次迭代。     ,        在Producer中,您设置了
consumerObj.consumerStatus = false;
并立即在循环条件下检查该值。循环在1个周期后结束。 后
count = count+1;
您应该等待(“消费”)。
try{
    this.wait();
} catch (Exception e) {
    e.printStackTrace();
}
消费者中的同样问题。循环中的最后一件事应该是
p.wait();
    ,        您应该使用BlockingQueues。 参见http://www.javamex.com/tutorials/synchronization_producer_consumer_2.shtml。 上面的实现效率低下,它迫使所有保险人阻止。 使用多个队列,可以防止所有使用者阻塞。 您可以在Google上找到示例。 Java.util.concurrent使用它是有原因的。