0

If I run the following program, the JVM will not terminate after execution. However, if I uncomment the line (// newFixedThreadPool.execute(new Producer3());) from the code, the program terminates after execution. I am aware because of the blocking nature of the queue the program does not terminate. In the context of the below code what part of the code blocks the termination of the JVM?

public class LinkedBlockingQueueExample {

    public static void main(String[] args) {

      final BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<String>(5);

      final class Producer implements Runnable {

        @Override
        public void run() {

            try {
                blockingQueue.put("Joshua");
                blockingQueue.put("Bloch");
                System.out.println("Put Joshua in the queue");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

      }

      final class Producer1 implements Runnable {

        @Override
        public void run() {

            try {
                blockingQueue.put("Martin");
                blockingQueue.put("Fowler");
                System.out.println("Put Mr Fowler in the Queue");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

      }

      final class Producer3 implements Runnable {

        @Override
        public void run() {

            try {
                blockingQueue.put("Malcom");
                blockingQueue.put("Gladwell");
                System.out.println("Put an Outlier in the Queue");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

    final class Consumer implements Runnable {

        @Override
        public void run() {
            try {
                System.out.println(getClass() + " " + blockingQueue.take());
                System.out.println(getClass() + " " + blockingQueue.take());
                System.out.println(getClass() + " " + blockingQueue.take());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    final class Consumer1 implements Runnable {

        @Override
        public void run() {
            try {
                System.out.println(getClass() + " " + blockingQueue.take());
                System.out.println(getClass() + " " + blockingQueue.take());
                System.out.println(getClass() + " " + blockingQueue.take());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);

    newFixedThreadPool.execute(new Producer());
    newFixedThreadPool.execute(new Producer1());
    // newFixedThreadPool.execute(new Producer3());
    newFixedThreadPool.execute(new Consumer());
    newFixedThreadPool.execute(new Consumer1());

    newFixedThreadPool.shutdown();

  }
}
M A
  • 71,713
  • 13
  • 134
  • 174
TheMonkWhoSoldHisCode
  • 2,182
  • 3
  • 26
  • 40

2 Answers2

1

Take() call is always blocking till elements become available.. if you don't want to block then user poll()

    poll()
Retrieves and removes the head of this queue, or returns null if this queue is empty.

reference : http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedBlockingQueue.html#poll()

c.sankhala
  • 850
  • 13
  • 27
0

The extra "take" is blocking the termination. It blocks on the extra "take"

TheMonkWhoSoldHisCode
  • 2,182
  • 3
  • 26
  • 40