2017-09-03 19 views
0

Ich führe Code für einen Hersteller und mehrere Verbraucher aus. Ich möchte die Ausführung von Consumer-Threads priorisieren. wenn ich consThread1, consThread2, consThread3. meine Frage ist, wie consThread3 zu beschränken, bevor consThread1 und consThread2Wie die Reihenfolge der Ausführung von Consumer-Threads beibehalten wird

Producer.java

import java.util.concurrent.BlockingQueue; 
import org.json.simple.JSONObject; 

public class Producer implements Runnable { 
    private final BlockingQueue<Message> sharedQueue; 

    @SuppressWarnings("unchecked") 
    public Producer(BlockingQueue<Message> sharedQueue){ 
     this.sharedQueue=sharedQueue; 
    } 

    @Override 
    public void run() { 
     try{ 
      for(int i=0;i<4;i++) { 
       Message msg=new Message(""+i); 
       System.out.println("Producer Produced: " +msg.getMessage()); 
       sharedQueue.put(msg); 
       Thread.sleep(400); 
      } 
      sharedQueue.put(new Message("exit")); // end of producing 
      System.out.println("-------Producer STOPPED------"); 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Consumer.java

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.TimeUnit; 
import org.json.simple.JSONObject; 

public class Consumer implements Runnable{ 

    private final BlockingQueue<Message> sharedQueue; 
    private String threadId; 

    public Consumer(BlockingQueue<Message> sharedQueue) {   
     this.sharedQueue=sharedQueue;   
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public void run() { 
     threadId = "Consumer-" + Thread.currentThread().getName(); 
     try { 
      Message msg; 
      while (true){ 
       msg=sharedQueue.poll(5,TimeUnit.SECONDS); 
       if(msg.getMessage()=="exit" || msg.getMessage()==null){ 
        sharedQueue.put(new Message("exit")); 
        break; 
       } 
       System.out.println(threadId + ": Consuming Message " + msg.getMessage()); 
       Thread.sleep(1000); 
      } 
      System.out.println(threadId + " STOPPED Consuming "); 
     } 
     catch (InterruptedException ie) { 
      ie.printStackTrace(); 
     } 
    } 
} 

Testprogramm ProducerConsumer.java

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.LinkedBlockingQueue; 
import org.json.simple.JSONObject; 

public class ProducerConsumer { 

    public static void main(String[] args) throws InterruptedException { 
     BlockingQueue<Message> sharedQueue = new LinkedBlockingQueue<>(10); 

     //Creating Producer and Consumer Thread 
     Thread prodThread = new Thread(new Producer(sharedQueue)); 
     Thread consThread1 = new Thread(new Consumer(sharedQueue)); 
     Thread consThread2 = new Thread(new Consumer(sharedQueue)); 
     Thread consThread3 = new Thread(new Consumer(sharedQueue)); 
     //Starting producer and Consumer thread 
     System.out.println("Producer and consumer threads started \n\n\n---------------------------------------"); 

     prodThread.start(); 
     consThread1.start(); 
     consThread2.start(); 
     consThread1.join(); 
     consThread2.join(); 
     consThread3.start(); 
    } 
} 
+1

Warum willst du das? – Kayaman

+7

Sie erstellen also drei Consumer-Threads, um 3 Elemente gleichzeitig verwenden zu können, möchten aber, dass sie nacheinander und nicht gleichzeitig konsumiert werden? Warum starte dann 3 Threads? Verwenden Sie einfach einen einzelnen Consumer-Thread, und der Verbrauch wird sequenziell sein. –

+0

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setPriority(int) aber zu beachten, wie JB wies darauf hin, warum drei Threads dann verwenden? – nullpointer

Antwort

-1

Wenn zu verbrauchen Sie möchten eine nach der anderen ausführen, warum verwenden Sie überhaupt mehrere Threads? Sie sollten nur zu einem einzelnen Thread umgestalten.

Wenn Sie jedoch das Refactoring überspringen möchten, können Sie die konsumierenden Threads einfach in einen festen Thread-Pool einfügen. In einem Thread-Pool können Sie die maximale Anzahl aktiver Threads festlegen, sodass Sie das Maximum auf eins festlegen können und der Thread-Pool die Threads nacheinander ausführt.

Eine weitere Alternative besteht darin, eine zyklische Barriere zu erstellen, bei der die Barrier-Aktion Ihr dritter Thread ist (sie wird nach den anderen aufgerufen). Sie können die ersten beiden Threads über die zyklische Barriere hinweg ausführen. Die Barriere kann die Finishing-Threads zählen und die dritte ausführen, wenn der Schwellenwert erreicht ist. Dies sollte Ihrem Ziel entsprechen, dass der dritte Consumer-Thread warten soll, bis das Ereignis konsumiert werden kann.

Verwandte Themen