如何维护消费者线程的执行顺序

时间:2017-09-03 13:52:56

标签: java multithreading producer-consumer

我正在为一个生产者和多个消费者运行代码。我想优先执行消费者线程。即如果我有consThread1,consThread2,consThread3。我的问题是如何在consThread1和consThread2

之前限制consThread3消耗

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 个答案:

答案 0 :(得分:-1)

如果要逐个执行,为什么要使用多个线程?你应该只重构一个线程。

但是,如果要跳过重构,可以将消费线程放入固定的线程池中。在线程池中,您可以设置最大活动线程数,因此您可以将最大值设置为1,线程池将逐个执行线程。

另一种方法是创建一个循环屏障,其中屏障操作是您的第三个线程(它将在其他线程之后调用)。您可以通过循环屏障执行前两个线程。屏障可以计算完成线程,并在达到阈值时执行第三个。这应该符合你的目标,即希望第三个消费者线程等到事件被消耗。