簡體   English   中英

Java 線程生產者消費者算法無法正常工作

[英]Java Threads Producer Consumer Algorithm not working properly

我正在嘗試學習線程,因此我編寫了一個示例生產者消費者問題,其中生產者產生從 1 到 10 的數字,而消費者必須顯示它們。 但只有消費者顯示數字 1 並停止。

正如我所說,該程序寫得不好,可能很荒謬,但我仍然想弄清楚為什么沒有打印從 1 到 10 的所有數字的原因,因為當我編寫代碼而不是從示例中時,我會記得最好。

我正在使用兩個變量來跟蹤生產者或消費者活動的完成情況,以便我可以執行另一個。

/ getStatus(Consumer 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;

}
}

Output:

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

在來自.. Suraj 的輸入之后.. 現在程序運行良好.. 見下文..

導入 java.lang.Math; 公共 class 你好{

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;

}

}

好的。 程序是錯誤的。

  1. 消費者線程到來並等待鎖定。
  2. 生產者循環中的第一次迭代將調用 notify,但不會釋放鎖,因為 while 循環位於同步塊內。 它將迭代 10 次而不釋放鎖,並最終連續調用 notify 10 次。
  3. 但是消費者只能喚醒一次,消費者第二次調用 wait() 時它會繼續等待,因為現在沒有人調用 notify(因為生產者的所有 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

上述實現效率低下,它迫使所有消費者阻止。 使用多個隊列,您可以防止所有消費者阻塞。 你可以在谷歌上找到例子。 Java.util.concurrent 使用它,它的存在是有原因的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM