Search code examples
javamultithreadingproducer-consumer

Some confusion about blockingqueue and multithreaded consumer


I'm working on some multithreaded code like this (a lot of details omitted because of relevance):

public class Producer {

    private static BlockingQueue<Transaction> transactionsQueue = new LinkedBlockingQueue<Transaction>();
    private static ArrayList<C> consumersList = new ArrayList<C>();

    public Producer(int a, int b) {
        for (int i = 0; i < a; i++)
            accountsList.add(new Account(i, DEFAULT_BALANCE));

        for (int i = 0; i < b; i++)
            consumersList.add(new Consumer());

        for (Consumer c : consumersList)
            c.start(); //question line of code
    }


    public class Consumer extends Thread{
        @Override
        public void run(){
            while (true) {
                try {
                    Transaction nextTransaction = transactionsQueue.take();

                    if(nextTransaction.equals(FINAL_TRANSACTION))
                        break;

                    Account acc = accountsList.get(nextTransaction.getTo());
                    acc.makeTransaction(nextTransaction);
                    System.out.println(acc);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String []args){
        try{
            launch(args[0], NUM_OF_ACCOUNTS, Integer.parseInt(args[1]));
        }catch (Exception e){
            System.out.println("Incorrect args. Starting with default arguments");
            launch(SMALL_FILE, NUM_OF_ACCOUNTS, NUM_OF_THREADS);
        }
    }

    private static void launch(String filename, int numOfAccounts, int numOfConsumers) {
        Producer bank = new Producer(numOfAccounts, numOfConsumers);
        bank.createTransactionsQueue(filename); //start putting into transactionsQueue
        bank.close();
    }
}

My question is when the program executes for (Consumer c : consumersList) c.start(); in the Producer's constructor, does the consumer threads's run() method immediately gets called? If so what happens when the transactionsQueue is empty -- because the I start to put into transactionsQueue at bank.createTransactionsQueue(filename); which is after the constructor is called (and consumer threads created).


Solution

  • does the consumer threads's run() method immediately gets called

    It will get called very shortly after. It's not the next line executed, but will be executed once the new thread actually starts.

    If so what happens when the transactionsQueue is empty

    The other threads running will be suspended until there is an element in the queue. For each element that gets placed one thread will be awaken to pull the element off the queue.