Встреча_в_Телемосте_11_08_24_20_03_54_—_запись.webm
227 MB
Для тех кто не смог победить блокировку Youtube и не желает заходить в Rutube выкладываю видео тут!
Смотрите на здоровье) 🫡
Но с вас подписка на Youtube и Rutube и делитесь этими видео, буду крайне благодарен!)))
#online_meeting
Смотрите на здоровье) 🫡
#online_meeting
ConcurrentLinkedQueue, внутреннее устройство, особенности и преимущества
ConcurrentLinkedQueue — это неконкурирующая неблокирующая очередь на основе связанного списка, предоставляемая в пакете java.util.concurrent. Она поддерживает высокую степень конкурентности благодаря использованию алгоритмов без блокировок (lock-free algorithms).
Особенности и преимущества
Неконкурирующая: Методы ConcurrentLinkedQueue реализованы таким образом, что могут использоваться несколькими потоками одновременно без необходимости явной синхронизации.
Неблокирующая: Основана на алгоритмах без блокировок, что позволяет избежать блокировок и взаимных блокировок, повышая производительность в условиях высокой конкурентности.
Поддержка FIFO (First-In-First-Out): Гарантирует, что элементы будут обрабатываться в порядке их добавления.
Внутреннее устройство
ConcurrentLinkedQueue использует алгоритм Майкла-скотта (Michael-Scott) для реализации неблокирующей очереди на основе связанного списка. Основные компоненты включают узлы (nodes) и ссылки на голову (head) и хвост (tail) очереди.
Внутренний класс Node:
Узел содержит элемент данных и ссылку на следующий узел.
Голова и хвост очереди:
Очередь хранит ссылки на голову и хвост, которые используются для вставки и удаления элементов.
Алгоритм Майкла-скотта:
Этот алгоритм основан на атомарных операциях, таких как compareAndSet, для безопасного обновления ссылок на узлы без использования блокировок.
Преимущества использования
Высокая производительность в многопоточных средах: Благодаря отсутствию блокировок, ConcurrentLinkedQueue показывает высокую производительность даже при большом количестве конкурирующих потоков.
Минимизация блокировок и ожиданий: Использование атомарных операций позволяет избежать задержек, связанных с блокировками.
Безопасность при многопоточном доступе: Методы очереди обеспечивают безопасность при доступе из нескольких потоков без дополнительной синхронизации.
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-queue-linkedblocking-concurrentlinked
https://www.geeksforgeeks.org/concurrentlinkedqueue-in-java-with-examples/
#Java #Training #Medium #ConcurrentLinkedQueue
ConcurrentLinkedQueue — это неконкурирующая неблокирующая очередь на основе связанного списка, предоставляемая в пакете java.util.concurrent. Она поддерживает высокую степень конкурентности благодаря использованию алгоритмов без блокировок (lock-free algorithms).
Особенности и преимущества
Неконкурирующая: Методы ConcurrentLinkedQueue реализованы таким образом, что могут использоваться несколькими потоками одновременно без необходимости явной синхронизации.
Неблокирующая: Основана на алгоритмах без блокировок, что позволяет избежать блокировок и взаимных блокировок, повышая производительность в условиях высокой конкурентности.
Поддержка FIFO (First-In-First-Out): Гарантирует, что элементы будут обрабатываться в порядке их добавления.
Внутреннее устройство
ConcurrentLinkedQueue использует алгоритм Майкла-скотта (Michael-Scott) для реализации неблокирующей очереди на основе связанного списка. Основные компоненты включают узлы (nodes) и ссылки на голову (head) и хвост (tail) очереди.
Внутренний класс Node:
Узел содержит элемент данных и ссылку на следующий узел.
private static class Node<E> {
volatile E item;
volatile Node<E> next;
Node(E item) {
this.item = item;
}
}
Голова и хвост очереди:
Очередь хранит ссылки на голову и хвост, которые используются для вставки и удаления элементов.
private transient volatile Node<E> head;
private transient volatile Node<E> tail;
Алгоритм Майкла-скотта:
Этот алгоритм основан на атомарных операциях, таких как compareAndSet, для безопасного обновления ссылок на узлы без использования блокировок.
public boolean offer(E e) {
final Node<E> newNode = new Node<>(e);
for (Node<E> t = tail, p = t; ; ) {
Node<E> q = p.next;
if (q == null) {
if (p.next = q) {
tail = newNode;
return true;
}
} else {
p = (t != tail) ? tail : q;
}
}
}
Преимущества использования
Высокая производительность в многопоточных средах: Благодаря отсутствию блокировок, ConcurrentLinkedQueue показывает высокую производительность даже при большом количестве конкурирующих потоков.
Минимизация блокировок и ожиданий: Использование атомарных операций позволяет избежать задержек, связанных с блокировками.
Безопасность при многопоточном доступе: Методы очереди обеспечивают безопасность при доступе из нескольких потоков без дополнительной синхронизации.
import java.util.concurrent.ConcurrentLinkedQueue;
public class ConcurrentLinkedQueueExample {
public static void main(String[] args) {
ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
// Вставка элементов
queue.offer(1);
queue.offer(2);
queue.offer(3);
// Извлечение элементов
System.out.println(queue.poll()); // 1
System.out.println(queue.poll()); // 2
System.out.println(queue.poll()); // 3
}
}
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-queue-linkedblocking-concurrentlinked
https://www.geeksforgeeks.org/concurrentlinkedqueue-in-java-with-examples/
#Java #Training #Medium #ConcurrentLinkedQueue
Baeldung
LinkedBlockingQueue vs ConcurrentLinkedQueue | Baeldung
Learn the difference between LinkedBlockingQueue and ConcurrentLinkedQueue in Java
Что выведет код?
#Tasks
import java.util.concurrent.ConcurrentLinkedQueue;
public class ConcurrentLinkedQueueChallenge {
public static void main(String[] args) {
ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
for (int i = 1; i <= 5; i++) {
queue.offer(i);
}
int result = 1;
for (int i = 0; i < 3; i++) {
Integer val = queue.poll();
if (val != null) {
result *= val;
}
queue.offer(result);
}
int sum = 0;
for (Integer val : queue) {
sum += val;
}
System.out.println("Sum: " + sum);
}
}
#Tasks
Мем для IQ > 100!😱
Внимание! Возможен перелом мозга! Будьте внимательнее!!!
https://t.me/Java_for_beginner_dev
#Mems
https://t.me/Java_for_beginner_dev
#Mems
Основные методы ConcurrentLinkedQueue и примеры использования
offer(E e):
Вставляет элемент в конец очереди. Возвращает true после успешного добавления.
poll():
Извлекает и удаляет элемент из головы очереди. Возвращает null, если очередь пуста.
peek():
Возвращает элемент из головы очереди без его удаления. Возвращает null, если очередь пуста.
isEmpty():
Проверяет, пуста ли очередь.
size():
Возвращает количество элементов в очереди. Обратите внимание, что этот метод может быть дорогим, так как требует полной итерации по очереди для подсчета элементов.
Примеры использования
Производитель-потребитель:
Очередь задач:
#Java #Training #Medium #ConcurrentLinkedQueue
offer(E e):
Вставляет элемент в конец очереди. Возвращает true после успешного добавления.
ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
queue.offer(1);
queue.offer(2);
poll():
Извлекает и удаляет элемент из головы очереди. Возвращает null, если очередь пуста.
Integer item = queue.poll();
System.out.println(item); // 1
peek():
Возвращает элемент из головы очереди без его удаления. Возвращает null, если очередь пуста.
Integer item = queue.peek();
System.out.println(item); // 2
isEmpty():
Проверяет, пуста ли очередь.
boolean isEmpty = queue.isEmpty();
System.out.println(isEmpty); // false
size():
Возвращает количество элементов в очереди. Обратите внимание, что этот метод может быть дорогим, так как требует полной итерации по очереди для подсчета элементов.
int size = queue.size();
System.out.println(size); // 1
Примеры использования
Производитель-потребитель:
import java.util.concurrent.ConcurrentLinkedQueue;
public class ProducerConsumerExample {
public static void main(String[] args) {
ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
// Производитель
new Thread(() -> {
for (int i = 0; i < 10; i++) {
queue.offer(i);
System.out.println("Produced: " + i);
}
}).start();
// Потребитель
new Thread(() -> {
for (int i = 0; i < 10; i++) {
Integer item;
while ((item = queue.poll()) == null) {
// Ожидание элемента
}
System.out.println("Consumed: " + item);
}
}).start();
}
}
Очередь задач:
import java.util.concurrent.ConcurrentLinkedQueue;
public class TaskQueueExample {
public static void main(String[] args) {
ConcurrentLinkedQueue<Runnable> taskQueue = new ConcurrentLinkedQueue<>();
// Запуск потока исполнителя задач
new Thread(() -> {
while (true) {
Runnable task = taskQueue.poll();
if (task != null) {
task.run();
}
}
}).start();
// Добавление задач в очередь
taskQueue.offer(() -> System.out.println("Task 1 executed"));
taskQueue.offer(() -> System.out.println("Task 2 executed"));
}
}
#Java #Training #Medium #ConcurrentLinkedQueue
DelayQueue, внутреннее устройство и преимущества
DelayQueue — это специализированная очередь из пакета java.util.concurrent, которая предназначена для хранения элементов до истечения их задержки. Она основана на приоритетной очереди и используется в ситуациях, где необходимо реализовать задержку выполнения задач.
Внутреннее устройство DelayQueue
DelayQueue реализует интерфейсы BlockingQueue и Queue. Она состоит из элементов, которые должны реализовать интерфейс Delayed. Этот интерфейс требует реализации метода getDelay(TimeUnit unit), который возвращает оставшееся время задержки элемента в указанных единицах.
Элементы DelayQueue:
Каждый элемент в DelayQueue должен реализовать интерфейс Delayed.
Внутренняя структура:
DelayQueue использует приоритетную очередь для хранения элементов. Это позволяет эффективно управлять элементами на основе их времени задержки.
Приоритетная очередь реализуется на основе кучи (heap), что обеспечивает логарифмическое время выполнения операций вставки и удаления.
Механизм блокировки:
DelayQueue использует методы ReentrantLock для обеспечения потокобезопасности. Это позволяет избежать гонок и обеспечивает корректное поведение в многопоточной среде.
Извлечение элементов:
При попытке извлечения элемента из DelayQueue, если задержка элемента еще не истекла, поток будет заблокирован до истечения задержки.
Преимущества DelayQueue
Управление задержками: DelayQueue идеально подходит для задач, где необходимо управлять задержками, таких как планирование задач или кэширование с истечением времени.
Потокобезопасность: Использование механизмов блокировки и приоритетной очереди обеспечивает безопасность в многопоточных приложениях.
Гибкость: Возможность использовать любые объекты, реализующие интерфейс Delayed, позволяет легко адаптировать DelayQueue под различные задачи.
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-delay-queue
https://habr.com/ru/articles/599603/
#Java #Training #Medium #DelayQueue
DelayQueue — это специализированная очередь из пакета java.util.concurrent, которая предназначена для хранения элементов до истечения их задержки. Она основана на приоритетной очереди и используется в ситуациях, где необходимо реализовать задержку выполнения задач.
Внутреннее устройство DelayQueue
DelayQueue реализует интерфейсы BlockingQueue и Queue. Она состоит из элементов, которые должны реализовать интерфейс Delayed. Этот интерфейс требует реализации метода getDelay(TimeUnit unit), который возвращает оставшееся время задержки элемента в указанных единицах.
Элементы DelayQueue:
Каждый элемент в DelayQueue должен реализовать интерфейс Delayed.
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
class DelayedElement implements Delayed {
private final long delayTime;
private final long creationTime;
public DelayedElement(long delayTime) {
this.delayTime = delayTime;
this.creationTime = System.currentTimeMillis();
}
@Override
public long getDelay(TimeUnit unit) {
long elapsedTime = System.currentTimeMillis() - creationTime;
return unit.convert(delayTime - elapsedTime, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) {
return -1;
}
if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
return 1;
}
return 0;
}
}
Внутренняя структура:
DelayQueue использует приоритетную очередь для хранения элементов. Это позволяет эффективно управлять элементами на основе их времени задержки.
Приоритетная очередь реализуется на основе кучи (heap), что обеспечивает логарифмическое время выполнения операций вставки и удаления.
Механизм блокировки:
DelayQueue использует методы ReentrantLock для обеспечения потокобезопасности. Это позволяет избежать гонок и обеспечивает корректное поведение в многопоточной среде.
private final transient ReentrantLock lock = new ReentrantLock();
private final Condition available = lock.newCondition();
Извлечение элементов:
При попытке извлечения элемента из DelayQueue, если задержка элемента еще не истекла, поток будет заблокирован до истечения задержки.
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
E first = q.peek();
if (first == null) {
available.await();
} else {
long delay = first.getDelay(TimeUnit.NANOSECONDS);
if (delay <= 0) {
return q.poll();
}
first = null;
available.awaitNanos(delay);
}
}
} finally {
lock.unlock();
}
}
Преимущества DelayQueue
Управление задержками: DelayQueue идеально подходит для задач, где необходимо управлять задержками, таких как планирование задач или кэширование с истечением времени.
Потокобезопасность: Использование механизмов блокировки и приоритетной очереди обеспечивает безопасность в многопоточных приложениях.
Гибкость: Возможность использовать любые объекты, реализующие интерфейс Delayed, позволяет легко адаптировать DelayQueue под различные задачи.
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-delay-queue
https://habr.com/ru/articles/599603/
#Java #Training #Medium #DelayQueue
Хабр
Полезные и неизвестные возможности Java
В этой статье вы узнаете о некоторых полезных функциях Java, о которых вы, вероятно, не слышали. Это мой личный список функций, использованных мной недавно или с которыми я столкнулся при чтении...
Что выведет код?
#Tasks
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
class DelayedElement implements Delayed {
private final long delayTime;
private final long creationTime;
public DelayedElement(long delayTime) {
this.delayTime = delayTime;
this.creationTime = System.currentTimeMillis();
}
@Override
public long getDelay(TimeUnit unit) {
long diff = creationTime + delayTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(this.getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS));
}
@Override
public String toString() {
return "DelayedElement{" + "delayTime=" + delayTime + '}';
}
}
public class DelayQueueChallenge {
public static void main(String[] args) throws InterruptedException {
DelayQueue<DelayedElement> queue = new DelayQueue<>();
queue.offer(new DelayedElement(1000));
queue.offer(new DelayedElement(2000));
queue.offer(new DelayedElement(3000));
long startTime = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < 3; i++) {
DelayedElement element = queue.take();
long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
sum += elapsedTime;
System.out.println("Taken: " + element + " at " + elapsedTime + " seconds");
}
System.out.println("Sum: " + sum);
}
}
#Tasks
Основные методы DelayQueue и примеры использования
add(E e):
Добавляет элемент в очередь. Если очередь полна, генерируется исключение.
put(E e):
Добавляет элемент в очередь. Если очередь полна, операция блокируется до освобождения места.
offer(E e):
Добавляет элемент в очередь, если это возможно. Возвращает true, если элемент был добавлен, и false в противном случае.
take():
Извлекает и удаляет элемент из головы очереди, ожидая при необходимости до истечения задержки.
poll(long timeout, TimeUnit unit):
Извлекает и удаляет элемент из головы очереди, ожидая до указанного времени, если необходимо.
clear():
Удаляет все элементы из очереди.
remove(Object o):
Удаляет указанный элемент из очереди, если он присутствует.
Примеры использования
Запланированные задачи:
DelayQueue можно использовать для планирования выполнения задач через определенные промежутки времени.
Кэширование с истечением срока действия:
DelayQueue можно использовать для реализации кэша, элементы которого удаляются по истечении определенного времени.
#Java #Training #Medium #DelayQueue
add(E e):
Добавляет элемент в очередь. Если очередь полна, генерируется исключение.
DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();
delayQueue.add(new DelayedElement(1000));
put(E e):
Добавляет элемент в очередь. Если очередь полна, операция блокируется до освобождения места.
delayQueue.put(new DelayedElement(2000));
offer(E e):
Добавляет элемент в очередь, если это возможно. Возвращает true, если элемент был добавлен, и false в противном случае.
boolean added = delayQueue.offer(new DelayedElement(3000));
take():
Извлекает и удаляет элемент из головы очереди, ожидая при необходимости до истечения задержки.
DelayedElement element = delayQueue.take();
poll(long timeout, TimeUnit unit):
Извлекает и удаляет элемент из головы очереди, ожидая до указанного времени, если необходимо.
DelayedElement element = delayQueue.poll(2, TimeUnit.SECONDS);
clear():
Удаляет все элементы из очереди.
delayQueue.clear();
remove(Object o):
Удаляет указанный элемент из очереди, если он присутствует.
delayQueue.remove(someElement);
Примеры использования
Запланированные задачи:
DelayQueue можно использовать для планирования выполнения задач через определенные промежутки времени.
import java.util.concurrent.DelayQueue;
public class ScheduledTaskExample {
public static void main(String[] args) throws InterruptedException {
DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();
// Добавление задач
delayQueue.put(new DelayedElement(3000)); // 3 секунды задержки
delayQueue.put(new DelayedElement(5000)); // 5 секунд задержки
// Обработка задач
while (!delayQueue.isEmpty()) {
DelayedElement element = delayQueue.take();
System.out.println("Task executed: " + element);
}
}
}
Кэширование с истечением срока действия:
DelayQueue можно использовать для реализации кэша, элементы которого удаляются по истечении определенного времени.
import java.util.concurrent.DelayQueue;
public class CacheExample {
private static class CacheItem implements Delayed {
private final String value;
private final long expiryTime;
public CacheItem(String value, long delay) {
this.value = value;
this.expiryTime = System.currentTimeMillis() + delay;
}
@Override
public long getDelay(TimeUnit unit) {
long delay = expiryTime - System.currentTimeMillis();
return unit.convert(delay, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if (this.expiryTime < ((CacheItem) o).expiryTime) {
return -1;
}
if (this.expiryTime > ((CacheItem) o).expiryTime) {
return 1;
}
return 0;
}
@Override
public String toString() {
return value;
}
}
public static void main(String[] args) throws InterruptedException {
DelayQueue<CacheItem> cache = new DelayQueue<>();
// Добавление элементов в кэш
cache.put(new CacheItem("Item1", 2000)); // 2 секунды жизни
cache.put(new CacheItem("Item2", 4000)); // 4 секунды жизни
// Извлечение элементов по истечении срока жизни
while (!cache.isEmpty()) {
CacheItem item = cache.take();
System.out.println("Expired item: " + item);
}
}
}
#Java #Training #Medium #DelayQueue
Всем привет!
(Установка активированной IntelliJ IDEA ideaIU-2024.2.0.1 Ulimate)
В связи с тем, что при отсоединении чата от канала, потерлись комментарии всех ранее опубликованных постов, вновь запилю гайд по установке взломанной версии IntelliJ IDEA Ulimate, да и всех остальных продуктов JetBrains заодно.(которые не хотят взаимодействовать с программистами из России 😡).
Итак:
1. Качаем с официального сайта https://www.jetbrains.com/ версию того продукта который вам нужен. Я использовал новейшую IntelliJ IDEA ideaIU-2024.2.0.1 (на момент написания поста), поэтому приложу ее к посту. (Кому-то может понадобиться VPN).
2. Качаем, приложенный в комментариях архив jetbra.zip
3. Распаковываем jetbra.zip в нужное вам место на Вашем компуктере, переходим в папку scripts и выполняем нужный скрипт и ждем окончания его работы (окошечко с кнопкой done):
- install-current-user.vbs — для текущего пользователя Windows
- install-all-users.vbs — для всех пользователей Windows
- install.sh — для MacOS и Linux
4. В папке расположения продукта (обычно такой путь - C:\Program Files\JetBrains\IntelliJ IDEA 2024.2.0.1\bin) находим файл idea64.exe.vmoptions и в нем проверяем наличие строки: -javaagent:C:\jetbra\ja-netfilter.jar=jetbrains. Если ее нет, дописываем ручками! (Внимательно проверяйте путь, по которому у Вас находится распакованный архив jetbra.zip).
5. По выбору: из приложенного в комментариях файла получаем ключ (строго для IntelliJ IDEA), или переходим на сайт https://3.jetbra.in, где в любом из активных хостов, выбираем необходимый для активации продукт и получаем в буфер ключ.
6. Запускаем продукт и переходим в вкладку Activation Code и вставляем скопированный ранее ключ.
Все! Ваш продукт активирован до 2026 года, что как я считаю более чем достаточно)))
Приятного использования и всем пожалуйста😉
#Installing_IDEA
(Установка активированной IntelliJ IDEA ideaIU-2024.2.0.1 Ulimate)
В связи с тем, что при отсоединении чата от канала, потерлись комментарии всех ранее опубликованных постов, вновь запилю гайд по установке взломанной версии IntelliJ IDEA Ulimate, да и всех остальных продуктов JetBrains заодно.
Итак:
1. Качаем с официального сайта https://www.jetbrains.com/ версию того продукта который вам нужен. Я использовал новейшую IntelliJ IDEA ideaIU-2024.2.0.1 (на момент написания поста), поэтому приложу ее к посту. (Кому-то может понадобиться VPN).
2. Качаем, приложенный в комментариях архив jetbra.zip
3. Распаковываем jetbra.zip в нужное вам место на Вашем компуктере, переходим в папку scripts и выполняем нужный скрипт и ждем окончания его работы (окошечко с кнопкой done):
- install-current-user.vbs — для текущего пользователя Windows
- install-all-users.vbs — для всех пользователей Windows
- install.sh — для MacOS и Linux
4. В папке расположения продукта (обычно такой путь - C:\Program Files\JetBrains\IntelliJ IDEA 2024.2.0.1\bin) находим файл idea64.exe.vmoptions и в нем проверяем наличие строки: -javaagent:C:\jetbra\ja-netfilter.jar=jetbrains. Если ее нет, дописываем ручками! (Внимательно проверяйте путь, по которому у Вас находится распакованный архив jetbra.zip).
5. По выбору: из приложенного в комментариях файла получаем ключ (строго для IntelliJ IDEA), или переходим на сайт https://3.jetbra.in, где в любом из активных хостов, выбираем необходимый для активации продукт и получаем в буфер ключ.
6. Запускаем продукт и переходим в вкладку Activation Code и вставляем скопированный ранее ключ.
Все! Ваш продукт активирован до 2026 года, что как я считаю более чем достаточно)))
Приятного использования и всем пожалуйста😉
#Installing_IDEA
Java for Beginner pinned «Всем привет! (Установка активированной IntelliJ IDEA ideaIU-2024.2.0.1 Ulimate) В связи с тем, что при отсоединении чата от канала, потерлись комментарии всех ранее опубликованных постов, вновь запилю гайд по установке взломанной версии IntelliJ IDEA Ulimate…»
SynchronousQueue
SynchronousQueue — это специализированная реализация интерфейса BlockingQueue, который позволяет передавать элементы между потоками напрямую. В отличие от других очередей, у SynchronousQueue нет внутреннего буфера или емкости. Каждый put-запрос должен соответствовать take-запросу, чтобы операция завершилась. Это делает SynchronousQueue полезной в ситуациях, когда требуется прямая передача данных между потоками.
Внутреннее устройство SynchronousQueue
SynchronousQueue можно представить как точку передачи данных, где один поток передает элемент, и другой поток немедленно его забирает. Если нет готового потребителя для передачи, операция будет заблокирована до тех пор, пока потребитель не появится.
Блокировка и синхронизация:
SynchronousQueue использует два режима передачи данных: "fair" (справедливый) и "non-fair" (несправедливый). В справедливом режиме потоки обслуживаются в порядке поступления (FIFO), тогда как в несправедливом режиме порядок не гарантируется.
Реализация на основе блокировки и синхронизации происходит с помощью ReentrantLock и Condition.
Режимы работы:
Fair Mode: Гарантирует обслуживание потоков в порядке поступления. Это достигается за счет использования очередей ожидания для операций put и take.
Non-Fair Mode: Потоки обслуживаются без строгого порядка, что может приводить к уменьшению времени ожидания для некоторых потоков, но не гарантирует равномерности.
Основные структуры данных:
В справедливом режиме используются две очереди ожидания для хранения ожидающих put и take операций.
В несправедливом режиме используется стек для выполнения операций.
Пример кода внутреннего устройства
Особенности SynchronousQueue
Отсутствие буферизации: У SynchronousQueue нет внутреннего буфера, что означает, что каждое добавление элемента должно совпадать с извлечением.
Потокобезопасность: Очередь разработана с учетом многопоточности и обеспечивает высокую степень безопасности для работы в конкурентной среде.
Высокая скорость передачи данных: За счет отсутствия буферизации и немедленной передачи элементов достигается высокая скорость обмена данными между потоками.
Гибкость: Возможность выбора между справедливым и несправедливым режимами работы позволяет оптимизировать производительность в зависимости от конкретных требований.
Преимущества SynchronousQueue
Эффективность в межпоточном взаимодействии: SynchronousQueue идеально подходит для ситуаций, где требуется немедленная передача данных между потоками, например, для реализации паттерна "производитель-потребитель".
Простота реализации: Очередь предоставляет простой API для обмена данными между потоками, что упрощает разработку многопоточных приложений.
Высокая производительность: За счет минимального количества операций по синхронизации достигается высокая производительность при обмене данными.
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-synchronous-queue
#Java #Training #Medium #SynchronousQueue
SynchronousQueue — это специализированная реализация интерфейса BlockingQueue, который позволяет передавать элементы между потоками напрямую. В отличие от других очередей, у SynchronousQueue нет внутреннего буфера или емкости. Каждый put-запрос должен соответствовать take-запросу, чтобы операция завершилась. Это делает SynchronousQueue полезной в ситуациях, когда требуется прямая передача данных между потоками.
Внутреннее устройство SynchronousQueue
SynchronousQueue можно представить как точку передачи данных, где один поток передает элемент, и другой поток немедленно его забирает. Если нет готового потребителя для передачи, операция будет заблокирована до тех пор, пока потребитель не появится.
Блокировка и синхронизация:
SynchronousQueue использует два режима передачи данных: "fair" (справедливый) и "non-fair" (несправедливый). В справедливом режиме потоки обслуживаются в порядке поступления (FIFO), тогда как в несправедливом режиме порядок не гарантируется.
Реализация на основе блокировки и синхронизации происходит с помощью ReentrantLock и Condition.
Режимы работы:
Fair Mode: Гарантирует обслуживание потоков в порядке поступления. Это достигается за счет использования очередей ожидания для операций put и take.
Non-Fair Mode: Потоки обслуживаются без строгого порядка, что может приводить к уменьшению времени ожидания для некоторых потоков, но не гарантирует равномерности.
Основные структуры данных:
В справедливом режиме используются две очереди ожидания для хранения ожидающих put и take операций.
В несправедливом режиме используется стек для выполнения операций.
Пример кода внутреннего устройства
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class SynchronousQueueExample {
public static void main(String[] args) {
SynchronousQueue<Integer> queue = new SynchronousQueue<>(true); // fair mode
Thread producer = new Thread(() -> {
try {
System.out.println("Putting element: 1");
queue.put(1);
System.out.println("Element 1 put");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
System.out.println("Taking element...");
Integer element = queue.take();
System.out.println("Element taken: " + element);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
Особенности SynchronousQueue
Отсутствие буферизации: У SynchronousQueue нет внутреннего буфера, что означает, что каждое добавление элемента должно совпадать с извлечением.
Потокобезопасность: Очередь разработана с учетом многопоточности и обеспечивает высокую степень безопасности для работы в конкурентной среде.
Высокая скорость передачи данных: За счет отсутствия буферизации и немедленной передачи элементов достигается высокая скорость обмена данными между потоками.
Гибкость: Возможность выбора между справедливым и несправедливым режимами работы позволяет оптимизировать производительность в зависимости от конкретных требований.
Преимущества SynchronousQueue
Эффективность в межпоточном взаимодействии: SynchronousQueue идеально подходит для ситуаций, где требуется немедленная передача данных между потоками, например, для реализации паттерна "производитель-потребитель".
Простота реализации: Очередь предоставляет простой API для обмена данными между потоками, что упрощает разработку многопоточных приложений.
Высокая производительность: За счет минимального количества операций по синхронизации достигается высокая производительность при обмене данными.
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-synchronous-queue
#Java #Training #Medium #SynchronousQueue
Baeldung
A Guide to Java SynchronousQueue | Baeldung
Learn how you can utilize Java's SynchronousQueue to help you coordinate the work of multiple threads.
Что выведет код?
#Tasks
import java.util.concurrent.*;
public class SynchronousQueueExample {
public static void main(String[] args) {
SynchronousQueue<Integer> queue = new SynchronousQueue<>();
Thread producer = new Thread(() -> {
try {
queue.put(1);
queue.put(2);
queue.put(3);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
try {
producer.join();
consumer.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
#Tasks
Основные методы SynchronousQueue и примеры использования
put(E e):
Добавляет элемент в очередь. Если нет готового потребителя, операция блокируется до тех пор, пока потребитель не появится.
take():
Извлекает и удаляет элемент из очереди. Если нет готового поставщика, операция блокируется до тех пор, пока элемент не будет добавлен.
offer(E e, long timeout, TimeUnit unit):
Пытается добавить элемент в очередь в течение заданного времени ожидания. Возвращает true, если элемент был добавлен, и false в противном случае.
poll(long timeout, TimeUnit unit):
Пытается извлечь элемент из очереди в течение заданного времени ожидания. Возвращает элемент или null, если время ожидания истекло.
isEmpty():
Возвращает true, если очередь пуста.
size():
Возвращает количество элементов в очереди. В случае SynchronousQueue всегда возвращает 0 или 1.
Примеры использования SynchronousQueue
Производитель-потребитель:
SynchronousQueue часто используется для реализации паттерна "производитель-потребитель", где производитель и потребитель обмениваются данными напрямую.
Синхронизация потоков:
SynchronousQueue можно использовать для синхронизации потоков, обеспечивая передачу сигналов между ними.
#Java #Training #Medium #SynchronousQueue
put(E e):
Добавляет элемент в очередь. Если нет готового потребителя, операция блокируется до тех пор, пока потребитель не появится.
SynchronousQueue<Integer> queue = new SynchronousQueue<>();
queue.put(1); // блокируется до появления потребителя
take():
Извлекает и удаляет элемент из очереди. Если нет готового поставщика, операция блокируется до тех пор, пока элемент не будет добавлен.
Integer element = queue.take(); // блокируется до появления элемента
offer(E e, long timeout, TimeUnit unit):
Пытается добавить элемент в очередь в течение заданного времени ожидания. Возвращает true, если элемент был добавлен, и false в противном случае.
boolean success = queue.offer(1, 2, TimeUnit.SECONDS); // попытка добавить элемент в течение 2 секунд
poll(long timeout, TimeUnit unit):
Пытается извлечь элемент из очереди в течение заданного времени ожидания. Возвращает элемент или null, если время ожидания истекло.
Integer element = queue.poll(2, TimeUnit.SECONDS); // попытка извлечь элемент в течение 2 секунд
isEmpty():
Возвращает true, если очередь пуста.
boolean empty = queue.isEmpty();
size():
Возвращает количество элементов в очереди. В случае SynchronousQueue всегда возвращает 0 или 1.
int size = queue.size();
Примеры использования SynchronousQueue
Производитель-потребитель:
SynchronousQueue часто используется для реализации паттерна "производитель-потребитель", где производитель и потребитель обмениваются данными напрямую.
import java.util.concurrent.SynchronousQueue;
public class ProducerConsumerExample {
public static void main(String[] args) {
SynchronousQueue<Integer> queue = new SynchronousQueue<>();
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Produced: " + i);
queue.put(i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
Integer item = queue.take();
System.out.println("Consumed: " + item);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
Синхронизация потоков:
SynchronousQueue можно использовать для синхронизации потоков, обеспечивая передачу сигналов между ними.
import java.util.concurrent.SynchronousQueue;
public class ThreadSyncExample {
public static void main(String[] args) {
SynchronousQueue<String> queue = new SynchronousQueue<>();
Thread thread1 = new Thread(() -> {
try {
System.out.println("Thread 1 waiting for signal...");
String signal = queue.take();
System.out.println("Thread 1 received signal: " + signal);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread thread2 = new Thread(() -> {
try {
Thread.sleep(2000);
queue.put("Start");
System.out.println("Thread 2 sent signal");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread1.start();
thread2.start();
}
}
#Java #Training #Medium #SynchronousQueue
LinkedTransferQueue, особенности и внутреннее устройство
LinkedTransferQueue — это неблокирующая очередь с дополнительными функциями для передачи данных, основанная на алгоритмах немедленной передачи данных между потоками. Эта очередь является частью пакета java.util.concurrent и предоставляет высокопроизводительную реализацию интерфейса TransferQueue, который является подинтерфейсом BlockingQueue.
Особенности LinkedTransferQueue
Неблокирующая реализация: Основана на неблокирующих алгоритмах, что позволяет избежать блокировок при выполнении операций вставки и извлечения, обеспечивая высокую производительность.
Поддержка передачи данных (transfer): Помимо стандартных операций добавления и удаления элементов, LinkedTransferQueue поддерживает операцию передачи данных (transfer), которая блокируется до тех пор, пока элемент не будет получен другим потоком.
Высокая производительность в многопоточной среде: Благодаря неблокирующим алгоритмам, LinkedTransferQueue обеспечивает высокую производительность и масштабируемость в многопоточных приложениях.
Упорядоченность: Очередь гарантирует упорядоченность элементов по принципу FIFO (First-In-First-Out).
Внутреннее устройство LinkedTransferQueue
Структура данных:
Основой очереди является односвязный список узлов, где каждый узел содержит элемент и ссылку на следующий узел.
Узлы могут быть двух типов: данные (data nodes) и запросы (request nodes). Узлы данных содержат элементы, а запросы — нет.
Алгоритмы и синхронизация:
Используется алгоритм CAS (Compare-And-Swap) для обеспечения атомарности операций и предотвращения блокировок.
При вставке элемента создается новый узел данных и пытается добавить его в конец очереди.
При извлечении элемента очередь ищет узел данных и удаляет его.
Операция передачи данных (transfer):
При вызове метода transfer, элемент добавляется в очередь и операция блокируется до тех пор, пока элемент не будет извлечен другим потоком.
Это достигается за счет специального состояния узлов и механизма ожидания/оповещения потоков.
Пример кода внутреннего устройства
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-transfer-queue
https://for-each.dev/lessons/b/-java-transfer-queue/
#Java #Training #Medium #LinkedTransferQueue
LinkedTransferQueue — это неблокирующая очередь с дополнительными функциями для передачи данных, основанная на алгоритмах немедленной передачи данных между потоками. Эта очередь является частью пакета java.util.concurrent и предоставляет высокопроизводительную реализацию интерфейса TransferQueue, который является подинтерфейсом BlockingQueue.
Особенности LinkedTransferQueue
Неблокирующая реализация: Основана на неблокирующих алгоритмах, что позволяет избежать блокировок при выполнении операций вставки и извлечения, обеспечивая высокую производительность.
Поддержка передачи данных (transfer): Помимо стандартных операций добавления и удаления элементов, LinkedTransferQueue поддерживает операцию передачи данных (transfer), которая блокируется до тех пор, пока элемент не будет получен другим потоком.
Высокая производительность в многопоточной среде: Благодаря неблокирующим алгоритмам, LinkedTransferQueue обеспечивает высокую производительность и масштабируемость в многопоточных приложениях.
Упорядоченность: Очередь гарантирует упорядоченность элементов по принципу FIFO (First-In-First-Out).
Внутреннее устройство LinkedTransferQueue
Структура данных:
Основой очереди является односвязный список узлов, где каждый узел содержит элемент и ссылку на следующий узел.
Узлы могут быть двух типов: данные (data nodes) и запросы (request nodes). Узлы данных содержат элементы, а запросы — нет.
Алгоритмы и синхронизация:
Используется алгоритм CAS (Compare-And-Swap) для обеспечения атомарности операций и предотвращения блокировок.
При вставке элемента создается новый узел данных и пытается добавить его в конец очереди.
При извлечении элемента очередь ищет узел данных и удаляет его.
Операция передачи данных (transfer):
При вызове метода transfer, элемент добавляется в очередь и операция блокируется до тех пор, пока элемент не будет извлечен другим потоком.
Это достигается за счет специального состояния узлов и механизма ожидания/оповещения потоков.
Пример кода внутреннего устройства
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
public class LinkedTransferQueueExample {
public static void main(String[] args) {
TransferQueue<Integer> queue = new LinkedTransferQueue<>();
Thread producer = new Thread(() -> {
try {
System.out.println("Producer: Transferring element 1");
queue.transfer(1);
System.out.println("Producer: Element 1 transferred");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
System.out.println("Consumer: Waiting to take element");
Integer element = queue.take();
System.out.println("Consumer: Taken element " + element);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-transfer-queue
https://for-each.dev/lessons/b/-java-transfer-queue/
#Java #Training #Medium #LinkedTransferQueue
Baeldung
Guide to the Java TransferQueue | Baeldung
Learn how the Java's TransferQueue can help you in writing multithreaded applications.