@@ -0,0 +1,2901 @@
+package org.andy.study.algorythms.lafore.chapter4;%0A%0Aimport java.util.LinkedList;%0Aimport java.util.List;%0Aimport java.util.Optional;%0Aimport java.util.Random;%0Aimport java.util.concurrent.BlockingQueue;%0Aimport java.util.concurrent.ExecutorService;%0Aimport java.util.concurrent.Executors;%0Aimport java.util.concurrent.LinkedBlockingQueue;%0Aimport java.util.logging.Level;%0Aimport java.util.logging.Logger;%0Aimport java.util.stream.Stream;%0A%0A/**%0A *%0A * @author andy%0A */%0Apublic class ShopQueueExample %7B%0A    public static void main(String%5B%5D args) %7B%0A        final ShopQueueExample queues = new ShopQueueExample();%0A        queues.start();%0A    %7D%0A    %0A    private static final int THREAD_COUNT = 5;%0A    private static final int SLEEP_TIME = 100;%0A    %0A    List%3CQueueThread%3E threads = new LinkedList%3C%3E();%0A    private ShopQueueExample() %7B%0A        for(int i = 0; i %3C THREAD_COUNT; i++) %7B%0A            threads.add(new QueueThread(i + 1));%0A        %7D%0A    %7D%0A%0A    private void start() %7B%0A        final ExecutorService pool = Executors.newFixedThreadPool(threads.size());%0A        threads.forEach(th -%3E %7Bpool.submit(th);%7D);%0A        int j = 0;%0A        while(true) %7B%0A            try %7B%0A                Thread.sleep(SLEEP_TIME);%0A                final Optional%3CQueueThread%3E minQueue = threads.stream().min((a, b) -%3E %7Breturn Integer.compare(a.size(), b.size());%7D);%0A                minQueue.get().insertItem(%22Consumer %22 + ++j);%0A            %7D catch (InterruptedException ex) %7B%0A                Logger.getLogger(ShopQueueExample.class.getName()).log(Level.SEVERE, null, ex);%0A            %7D%0A        %7D%0A    %7D%0A    %0A    static class QueueThread implements Runnable %7B%0A        private final BlockingQueue%3CString%3E queue;%0A        private final int number;%0A        private final Random rand = new Random(hashCode());%0A        %0A        public QueueThread(int number) %7B%0A            queue = new LinkedBlockingQueue%3C%3E();%0A            this.number = number;%0A        %7D%0A        %0A        public void insertItem(String item) %7B%0A            System.out.println(%22Queue %22 + number + %22Adding %22 + item + %22. Size: %22 + size());%0A            queue.add(item);%0A        %7D%0A        %0A        @Override%0A        public void run() %7B%0A            Thread.currentThread().setName(%22Queue %22 + number);%0A            while(true) %7B%0A                try %7B%0A                    final String item = queue.take();%0A                    print(%22Started working on %22 + item);%0A                    Thread.sleep(rand.nextInt(1000) + 100);%0A                    print(%22Stopped working on %22 + item);%0A                %7D catch (InterruptedException ex) %7B%0A                    Logger.getLogger(ShopQueueExample.class.getName()).log(Level.SEVERE, null, ex);%0A                %7D%0A            %7D%0A        %7D%0A%0A        private void print(String message) %7B%0A            System.out.println(Thread.currentThread().getName() + %22: %22 + message);%0A        %7D%0A%0A        private int size() %7B%0A            return queue.size();%0A        %7D%0A    %7D%0A%7D%0A

Chapter 4. Exercise 5