Пул задач блокирующая очередь

139
24 октября 2018, 04:10
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class ThreadPool {
    private final List<Thread> threads = new LinkedList<>();
    private final Queue<Runnable> tasks = new LinkedBlockingQueue<>(); //вообще это блокирующая очередь
    ThreadPool(int size) {                 //инициализация пула
        System.out.println(size + " ядер" + " создаю столько же нитий");
        for (int i = 0; i < size; i++) {
            this.threads.add(new ThreadList(this.tasks, "поток № " + i));
        }
    }
    //добавляем таски
    public void work(Runnable job) {
        tasks.offer(job);
    }
    //из этих тредов будет состоять линкедлист
    private static class ThreadList extends Thread {
        private final Queue<Runnable> task;
        Thread t;
        ThreadList(Queue<Runnable> queou, String name) {
            t = this;
            t.setName(name);
            System.out.println("создаю поток " + name);
            this.task = queou;
            start();                                                // поток сразу стартует
            try {
                join();                                               //главный поток будет ждать пока этот не завершится
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            Runnable r = task.poll(); //я думал блокирующая очередь и здесь должно сработать wait(); и поток бы освободил монитор для следующего потока и ждал своей очереди
            new Thread(r).start();
        }
    }
}

как мне сделать чтобы Треды запущенные ждали? зачем такая блокирующая очередь у которой wait отсутствует чем она блокирующая? вообще правильно ли я делаю пул потоков?

пытался сделать так

@Override
        public void run() {         
            while (!Thread.interrupted()) {
                while (task.isEmpty()) {
                    System.out.println("Жду");
                    try {
                        task.wait();    //вот тут запара какая то я вроде хочу чтоб очередь ждала если она пустая а у меня ошибки в миониторе идут
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                    Thread stTask = new Thread(task.poll()); // получается что мы каждый поток разбили ещё на нити и создавали
                    stTask.start();
                    System.out.println(stTask.getName());
                    try {
                        stTask.join();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
            }
        }

в мониторе ошибки посыпались

2 ядер создаю столько же нитий
создаю поток поток № 0
Жду
Exception in thread "поток № 0" java.lang.IllegalMonitorStateException
    at java.base/java.lang.Object.wait(Native Method)
    at java.base/java.lang.Object.wait(Object.java:328)
    at ru.job4j.pool.ThreadPool$ThreadList.run(ThreadPool.java:57)
создаю поток поток № 1
Жду
Exception in thread "поток № 1" java.lang.IllegalMonitorStateException
    at java.base/java.lang.Object.wait(Native Method)
    at java.base/java.lang.Object.wait(Object.java:328)
    at ru.job4j.pool.ThreadPool$ThreadList.run(ThreadPool.java:57)
Answer 1

Блокирующая очередь от обычной отличается наличием операции добавления, с блокировкой текущего потока, если очередь заполнена, и операцией извлечения с блокировкой текущего потока, если очередь пуста.

Пример использования - система публикатор - подписчик.

Зы. Извините что только текстом, пишу с телефона.

Answer 2

Runnable r = task.poll(); //я думал блокирующая очередь и здесь должно сработать wait(); и поток бы освободил монитор для следующего потока и ждал своей очереди

как мне сделать чтобы Треды запущенные ждали? зачем такая блокирующая очередь у которой wait отсутствует чем она блокирующая?

Согласно документации метод poll() не ждет элементы, а возвращает null:

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

Для ожидания доступности элементов вам нужно использовать методы

poll(long timeout, TimeUnit unit)

или

take()

Используйте интерфейс BlockingQueue вместо Queue

READ ALSO
Два ResultSet в сервлете

Два ResultSet в сервлете

такой вот вопрос, можно ли использовать два ResultSet в одном сервлете или нет? При использовании второго ResultSet выдает ошибку: orgpostgresql

152
Достать из строки числа, включая пробелы

Достать из строки числа, включая пробелы

Есть текстовый документ со строкамиСтроки содержат:

170
Независимое текущее время в Java (Android)

Независимое текущее время в Java (Android)

Пишу приложение, логика которого требует подключаться к серверу для обновления раз в годНо дата в системе пользователя может быть установлена...

166
Как проверить клик в Android Studio

Как проверить клик в Android Studio

Я создаю мини игру в Android StudioПри клике View меняет цвет

151