public static void main(String[] args) throws InterruptedException {
        final LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();

        List<Thread> consumers = new ArrayList<>();
        List<Thread> producers = new ArrayList<>();

        // start 20 consumers
        for(int i =0; i< 20; i++) {
            consumers.add(new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println();
                    try {
                        System.out.println("Thread :" +Thread.currentThread().getName()+ "Took : " + queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }));

            producers.add(new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println();
                    try {
                        System.out.println("Thread "+Thread.currentThread().getName()+ "Put : " +Thread.currentThread().getName());
                        queue.put(Integer.parseInt(Thread.currentThread().getName()));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }));

        }

        // start all the 20 consumers
        for( int i = 0; i< 20; i++) {
            consumers.get(i).setName(String.valueOf(i));
            consumers.get(i).start();
        }

       Thread.sleep(5000);

        // start all the 20 producers
        for( int i = 0; i< 20; i++) {
            producers.get(i).setName(String.valueOf(i));
            producers.get(i).start();
        }


        // wait till they all join
        for( int i = 0; i< 20; i++) {
           producers.get(i).join();
           consumers.get(i).join();
        }

    }