首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java线程生产者消费者算法不能正常工作

Java线程生产者消费者算法不能正常工作
EN

Stack Overflow用户
提问于 2011-05-30 13:59:42
回答 3查看 5.5K关注 0票数 3

我正在努力学习线程,因此我编写了一个示例生产者消费者问题,其中生产者产生的数字从1到10,消费者必须显示它们。但只有消费者才会显示数字1并停止。

正如我说的,这个程序写得不好,而且可能很荒谬,但我仍然想弄清楚为什么从1到10的所有数字都没有打印出来,因为我会记得,当我编写代码时,而不是从示例中。

我使用两个变量来跟踪产品或消费者活动的完成,以便我可以执行另一个。

/getStatus(消费者C)传递消费者引用,以使生产者获得对消费者的参考。并且它可以用来了解消费者..thats的状态。

代码语言:javascript
运行
复制
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;

}
}

产出:

代码语言:javascript
运行
复制
---1
---2
---3
---5
---4
---6
---9
---8
---7
the produced item is ----->1
---10

在……的输入之后。苏拉杰..。现在这个程序运行得很好。见下文..。

导入java.lang.Math;公共类Hello{

代码语言:javascript
运行
复制
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;

}

}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-05-30 14:28:41

好的。这个程序是错的。

  1. ,使用者线程来了,等待锁。生产者循环中的第一个迭代
  2. 将调用通知,但不会释放锁,因为while循环在同步块中。它将在不释放锁的情况下迭代10次,并最终调用continuously.
  3. But 10次消费者只需要唤醒一次,而第二次消费者调用wait()时它会继续等待,因为现在没有人需要调用通知(因为生产者的所有10个迭代都结束了)

因此,问题是消费者线程正在等待,但没有人通知它,因为生产者在一次中完成了全部10次迭代。

票数 3
EN

Stack Overflow用户

发布于 2011-05-30 14:10:16

在制片人里,你

代码语言:javascript
运行
复制
consumerObj.consumerStatus = false;

并立即在循环条件下检查此值。循环在一个周期后结束。之后

代码语言:javascript
运行
复制
count = count+1;

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

代码语言:javascript
运行
复制
try{
    this.wait();
} catch (Exception e) {
    e.printStackTrace();
}

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

代码语言:javascript
运行
复制
p.wait();
票数 0
EN

Stack Overflow用户

发布于 2011-08-30 16:36:13

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

上面的实现是无效的,它迫使所有的理解者阻止。使用多个队列,可以防止所有使用者阻塞。你可以在谷歌上找到例子。Java.util.concurrent使用它,这是有原因的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6177247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档