Рубрики
Без рубрики

Понимание Очереди блокировки В Java

Интерфейс BlockingQueue в Java был впервые представлен в Java 1.5. Интерфейс BlockingQueue поддерживает fl… Помеченный java.

Интерфейс BlockingQueue в Java был впервые представлен в Java 1.5. Интерфейс BlockingQueue поддерживает управление потоком, вводя блокировку, если очередь блокировки заполнена или пуста. Все методы BlockingQueue являются атомарными по своей природе и используют внутренние блокировки или другие формы контроля параллелизма.

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

BlockingQueue не принимает нулевое значение.

Интерфейс BlockingQueue является частью java collections framework пакета “java.util.concurrent” наряду с различными другими параллельными классами утилит, такими как ConcurrentHashMap, семафор подсчета, CopyOnWriteArrrayList и т. Д.

Java предоставляет несколько реализаций очереди блокировки, таких как:

  • Связанная очередь блокировки
  • Массивблокирующая очередь
  • Приоритетность блокировки очереди
  • Синхронная очередь

Теперь давайте рассмотрим каждую из этих указанных реализаций BlockingQueue с примерами, чтобы иметь четкое представление.

Связанная очередь блокировки

LinkedBlockingQueue сохраняет элементы внутри связанной структуры (связанные узлы) и использует порядок FIFO (Первый вход, первый выход) . При желании эта связанная структура может дополнительно иметь верхнюю границу. Если верхняя граница не указана, Целое число. MAX_VALUE используется в качестве верхней границы.

Вот как создать экземпляр и использовать LinkedBlockingQueue :

Пример BlockingQueue класс в приведенном ниже примере запускает Производителя и/| Потребитель в отдельных потоках. Производитель вставляет строки в очередь блокировки, а Потребитель извлекает их.

public class BlockingQueueExample {

    public static void main(String[] args) throws Exception {
        BlockingQueue unbounded = new LinkedBlockingQueue();
        BlockingQueue bounded   = new LinkedBlockingQueue(1024);

        new Thread(new Producer(bounded)).start();
        new Thread(new Consumer(bounded)).start();

        Thread.sleep(4000);
    }
}

Производитель класс , который вставляет строки в блокирующую очередь .

public class Producer implements Runnable {
    protected BlockingQueue queue = null;

    public Producer(BlockingQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            queue.put("Item #1");
            Thread.sleep(1000);
            queue.put("Item #2");
            Thread.sleep(1000);
            queue.put("Item #3");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

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

public class Consumer implements Runnable {
    protected BlockingQueue queue = null;

    public Consumer(BlockingQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            System.out.println(queue.take());
            System.out.println(queue.take());
            System.out.println(queue.take());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Массивблокирующая очередь

ArrayBlockingQueue представляет собой ограниченную очередь блокировки, аналогичную LinkedBlockingQueue, которая хранит элементы внутри массива в порядке FIFO (Первый вход, первый выход) . Верхняя граница для этого BlockingQueue устанавливается во время создания экземпляра, и после создания экземпляра она не может быть изменена.

Вот как создать экземпляр и использовать ArrayBlockingQueue :

BlockingQueue queue = new ArrayBlockingQueue(1024);

queue.put("ArrayBlockingQueue item: #1");

System.out.println(queue.take());

Приоритетность блокировки очереди

В отличие от LinkedBlockingQueue и Очередь блокировки массива , PriorityBlockingQueue – это неограниченная параллельная очередь. Он следует тем же правилам упорядочения, что и java.util. Приоритетная очередь класс и мы не можем вставить null в эту очередь.

В java.lang. Сопоставимый интерфейс должен быть реализован всеми элементами, которые вставляются в очередь PriorityBlockingQueue . Таким образом, элементы упорядочиваются в соответствии с любым приоритетом, который мы определяем в нашей сопоставимой реализации.

Обратите внимание, что PriorityBlockingQueue не обеспечивает какого-либо определенного поведения для элементов с равным приоритетом (сравните()). Также в случае, когда мы получаем итератор из очереди блокировки приоритетов, итератор не гарантирует повторение элементов в порядке приоритета.

Вот как создать экземпляр и использовать PriorityBlockingQueue :

BlockingQueue queue = new PriorityBlockingQueue();

//String class implements java.lang.Comparable
queue.put("PriorityBlockingQueue item: #1");

System.out.println(queue.take());

Синхронная очередь

Синхронная очередь – это очередь, которая может содержать только один элемент внутри и поддерживает только две операции: put() и взять() .

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

Хотя SynchronousQueue имеет интерфейс очереди, мы должны думать о нем как о точке обмена для одного элемента между двумя потоками.

Сообщение Понимание очереди блокировки в Java появилось первым в Журнале разработчика .

Оригинал: “https://dev.to/eightbytestech/understanding-blockingqueue-in-java-3lkm”