2016-08-07 30 views
1

Ich versuche, ein Producer-Consumer-Programm in Java zu schreiben, wo der Produzent 3 Nummern in eine Warteschlange einfügt und der Verbraucher diese Nummern aus der Warteschlange entfernt. Ich habe meine eigene Queue basierend auf meiner eigenen Linkedlist-Implementierung implementiert.Java Threads Produzent Consumer Programm

Wenn ich meinen Code ausführen, wird mein Producer beendet, aber mein Consumer wird nie beendet. Ich bin nicht in der Lage, um herauszufinden, warum

public class ProdConMain { 

public static void main(String[] args) throws InterruptedException { 

    MyQueue queue = new MyQueue(); 
    queue.setLimit(3); 
    Thread producer = new Thread(new Producer(queue)); 
    Thread consumer = new Thread(new Consumer(queue)); 

    producer.start(); 
    consumer.start(); 


    try { 
     producer.join(); 
     System.out.println("Producer: " + producer.getState()); 
     consumer.join(); 

     System.out.println("Consumer: " + consumer.getState()); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    System.out.println(queue.list.toString()); 

} 


} 



public class Producer implements Runnable { 

MyQueue queue = new MyQueue(); 
Random random = new Random(); 
public Producer(MyQueue queue) { 
    this.queue = queue; 
} 

@Override 
public void run() { 
    int i = 1; 
    while (i < 10) { 

     synchronized (queue) { 
      if (queue.getSize() < queue.getLimit()) { 
       int value = random.nextInt(500); 
       queue.enqueue(value); 
       System.out.println("Inserted: " + value); 
       queue.notify(); 
      } else { 
       try { 
        queue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     i++; 
    } 
    } 
} 


public class Consumer implements Runnable { 

    MyQueue queue = new MyQueue(); 

    public Consumer(MyQueue queue) { 
    this.queue = queue; 
} 

    @Override 
    public void run() { 

    while (true) { 
     synchronized (queue) { 

      if (queue.isEmpty()) { 
       { 
        try { 
         queue.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } else { 
       int value = queue.dequeue(); 
       System.out.println("Removed:  " + value); 
       queue.notify(); 
      } 
     } 
    } 
    } 
} 
+0

'Consumer' wird nie beendet, weil Sie Endlosschleife verwenden' while (true) ' –

Antwort

0

Sie benötigen einen Stoppzustand zu dieser while (true) Schleife in dem Verbraucher an, sonst wird es nie zu Ende. Sie können ihn unter der Bedingung während tun sich:

while(shouldConsume()) { 
    // consume ... 
} 

oder durch die Endlosschleife zu brechen, wenn die Bedingung erreicht ist:

while(true) { 
    // consume ... 

    if (shouldStopConsume()) { 
     break; 
    } 
} 

Und dann müssen Sie nur diese Methoden mit dem Anschlag implementieren Zustand, der zu Ihrem Anwendungsfall passt.

+0

Ich sehe, Danke. Es funktioniert jetzt für mich. Queue-Klasse - public volatile boolean doneProcessing; (Instanzvariable) Producer-Klasse - queue.doneProcessing = true; (nach dem Beenden der While-Schleife) Consumer-Klasse - while (! queue.doneProcessing) – Jehan