2017-09-03 111 views
0

我正在爲一個生產者和多個消費者運行代碼。我想優先執行消費者線程。即如果我有consThread1,consThread2,consThread3。我的問題是如何限制consThread3 consThread1和consThread2如何維護消費者線程的執行順序

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(); 
     } 
    } 
} 

測試程序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

你爲什麼要這樣? – Kayaman

+7

因此,您要創建三個消費者線程,以便能夠同時使用3個項目,但實際上您希望它們按順序使用,而不是同時使用?爲什麼要啓動3個線程呢?只需使用單個消費者線程,並且消費將是連續的。 –

+0

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setPriority(int)但要注意,因爲JB指出,爲什麼使用三個線程呢? – nullpointer

回答

-1

如果你想一個接一個地執行,爲什麼你使用多線程呢?你應該重構一個線程。

但是,如果你想跳過重構,你可以把消耗線程放到一個固定的線程池中。在線程池中,可以設置活動線程的最大數量,因此您可以將最大值設置爲1,並且線程池將逐個執行線程。

另一種選擇是創建一個循環障礙,其中障礙動作是您的第三個線程(它將在其他線程之後被調用)。您可以通過循環障礙執行前兩個線程。屏障可以統計整理線程,並在達到閾值時執行第三個線程。這應該符合你希望第三個消費者線程等待事件消耗的目標。