0

I am running code for one producer and multiple consumers. I want to prioritize execution of consumer threads. i.e. if I have consThread1, consThread2, consThread3. my question is how to restrict consThread3 to consume before consThread1 and 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();
        }
    }
}

Test program 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();
    }
}
Abhishek Nehe
  • 45
  • 1
  • 8
  • 1
    Why do you want that? – Kayaman Sep 03 '17 at 13:55
  • 7
    So, you're creating three consumer threads, in order to be able to consume 3 items concurrently, but you actually want them to consume sequentially, and not concurrently? Why start 3 threads then? Just use a single consumer thread, and consumption will be sequential. – JB Nizet Sep 03 '17 at 13:55
  • http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setPriority(int) but to note as JB pointed out, why use three threads then? – Naman Sep 03 '17 at 13:56
  • there is dependency between those 3 consumer threads. and that condition is that those 3 consumer threads should execute in order. – Abhishek Nehe Sep 03 '17 at 13:57
  • 1
    think about it. It doesn't make sense to start each one in their own thread if they are to run sequentially. JB Nizet's making all the sense :) – Jack Flamp Sep 03 '17 at 13:59
  • 1
    You're still missing the point. There's no reason to have multiple consumers if only one is allowed to work at a time. A single one is sufficient. – JB Nizet Sep 03 '17 at 14:04
  • i have consumers A,B,C. I want to restrict C to consume before A and B. Now is this possible ? – Abhishek Nehe Sep 03 '17 at 14:05
  • I alreay have helped. I told you, several times, as others have, that you should use a single consumer thread. But you won't listen and keep repeating the same thing again and again. – JB Nizet Sep 03 '17 at 14:13

1 Answers1

-1

If you want to execute one-by-one, why do you use multiple threads at all? You should just refactor to a single thread.

However, if you want to skip the refactoring, you can just put the consuming threads into a fixed thread pool. In a thread pool, you can set the maximum number of active threads, so you can set the maximum to one and the thread pool will execute the threads one by one.

Another alternative is to create a cyclic barrier where the barrier action is your third thread (it will be invoked after the others). You can execute the first two thread through the cyclic barrier. The barrier can count the finishing threads and will execute the third when the threshold reached. This should meet your goal of wanting for the 3rd consumer thread to wait until the event can be consumed.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Zsolt V
  • 517
  • 3
  • 8