Java. Основи неблокуючого I/O

Блокуюче I/O

Що таке блокуючі виклики?

Блокуючі виклики в Java - це операції вводу/виводу (I/O), які зупиняють виконання поточного потоку, доки дані не будуть повністю прочитані або записані. Наприклад, при читанні даних з файлу або при виконанні мережевого запиту.

Що відбувається з потоком під час блокуючого виклику?

Під час мережевого запиту, якщо дані ще не готові, потік, який виконує блокуючий виклик, заморожується. Це означає, що він не може виконувати інші завдання або обробляти інші запити, поки не отримає відповідь.

Який системний виклик використовується?

Під капотом, для мережевих операцій, використовуються системні виклики, такі як `read()` та `write()` в Unix-подібних системах. Ці виклики звертаються до операційної системи для виконання I/O операцій.

Чому ми чекаємо?

Потік чекає, бо ОС повинна виконати операцію I/O, яка може вимагати часу - наприклад, чекати на отримання даних з мережі або завершення читання диска.

Неблокуюче I/O

Що таке неблокуючий виклик?

Неблокуюче I/O дозволяє потоку продовжувати виконання, навіть коли дані ще не готові. Замість того, щоб зупинятися і чекати, потік може перевірити статус операції і, якщо дані недоступні, зайнятися іншими завданнями.

Неблокуючі мережеві системні виклики ядра

Системи, які підтримують неблокуюче I/O, використовують механізми, такі як `epoll` в Linux, `kqueue` в BSD, які дозволяють потокам ефективно моніторити кілька I/O потоків без блокування.

1. epoll у Linux:

  • epoll - це механізм введення-виведення, який дозволяє ефективно моніторити кілька файлових дескрипторів.

  • Він використовується для реалізації неблокуючих і асинхронних I/O операцій.

  • epoll працює з подією, підписуючись на різні типи подій для кожного дескриптора, і повідомляє програму, коли ці події настають, замість того, щоб чекати на завершення I/O.

2. kqueue у BSD:

  • kqueue - аналогічний механізм, який використовується в BSD-подібних системах.

  • Він також дозволяє моніторити різноманітні події, включаючи файли, сокети та таймери.

  • kqueue ефективно обробляє велику кількість подій, зменшуючи навантаження на систему.

В Java NIO з’явилася можливість створити потік, який знатиме, який канал готовий для запису та читання даних і може обробляти цей конкретний канал. Це реалізується за допомогою класу Selector.

Уявімо, що у вас є сервер, який одночасно обслуговує багато клієнтів через мережу. Замість того, щоб створювати новий потік для кожного клієнта (що може бути неефективним та витратним з точки зору ресурсів), ви використовуєте один потік і Selector.

Selector працює як централізований менеджер, який стежить за всіма з'єднаннями. Коли клієнт надсилає запит до сервера, Selector визначає, яке з'єднання готове до обробки (наприклад, прийому або відправки даних). Це дозволяє серверу ефективно переключатися між багатьма з'єднаннями, використовуючи невелику кількість потоків.

Цей підхід особливо корисний у ситуаціях, де сервер повинен одночасно обробляти значну к-ть з'єднань, але кожне з'єднання активно лише частину часу — веб-сервери, чат-сервера, ігри, etc.

15

Неблокуюче I/O дозволяє потоку продовжувати виконання інших завдань, поки очікується на введення-виведення. Це підвищує загальну ефективність, дозволяючи одному потоку обробляти декілька I/O операцій одночасно, не даючи потоку “простоювати“.

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Oleksandr Klymenko
Oleksandr Klymenko@overpathz

Java Software Engineer

4.4KПрочитань
1Автори
71Читачі
На Друкарні з 19 квітня

Більше від автора

  • Secure networking. Deep Dive

    Глибоке занурення в протоколи TLS/SSL та інфраструктуру відкритих ключів (PKI). Основні поняття, процес встановлення захищеного з'єднання, роль сертифікатів та ланцюжка довіри

    Теми цього довгочиту:

    Security
  • Поширені помилки у дизайні REST API

    У довгочиті розглядаються поширені помилки при проектуванні REST API та способи їх уникнення: версіонування, використання DTO, підхід CQRS, робота з мікросервісами, та інші практики для підвищення продуктивності, безпеки й зручності API

    Теми цього довгочиту:

    Java
  • Java. Короткий огляд еволюції багатопотоковості

    У перших версіях Java багатопоточність реалізовувалася за допомогою класу Thread, який дозволяв створювати нові потоки. Проте ця модель мала багато недоліків:

    Теми цього довгочиту:

    Java

Вам також сподобається

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Вам також сподобається