RingBuffer — учебный Java-проект, реализующий потокобезопасный кольцевой буфер (circular buffer / ring buffer) с фиксированной ёмкостью.
Кольцевой буфер — это структура данных типа FIFO, использующая один и тот же массив фиксированного размера так, что после достижения конца записи продолжаются с начала. Применяется в задачах буферизации потоков данных, межпоточного взаимодействия по схеме «производитель-потребитель», обработки сигналов и журналирования.
Основные возможности:
- 🧵 Потокобезопасная работа за счёт
ReentrantLockи прерываемой блокировкиlockInterruptibly(). - 🔢 Атомарный счётчик элементов на базе
AtomicInteger. - 🛡️ Контроль состояния буфера: проверки на переполнение, пустоту и закрытие.
- ♻️ Поддержка
AutoCloseableдля корректного освобождения ресурсов черезtry-with-resources. - 🚀 Демонстрационное приложение с двумя потоками (producer / consumer).
- ⚙️ Обобщённый тип
RingBuffer<T>— можно хранить элементы любого типа.
| Категория | Технология |
|---|---|
| Язык | Java |
| Сборка | Apache Maven |
| Тестирование | JUnit 3.8.1 |
| Логирование | com.sun.org.slf4j.internal (внутренний JDK SLF4J shim) |
| Конкурентность | java.util.concurrent (ReentrantLock, AtomicInteger) |
RingBuffer/
├── pom.xml # Maven-конфигурация и зависимости
├── README.md # Документация проекта
├── .gitignore
└── src/
├── main/
│ └── java/
│ └── com/puchkov/
│ ├── App.java # Демо: producer + consumer
│ ├── RingBuffer.java # Реализация кольцевого буфера
│ └── BufferFullException.java # Исключение при переполнении
└── test/
└── java/
└── com/puchkov/
└── AppTest.java # Заготовка JUnit-теста
Ключевые классы:
com.puchkov.RingBuffer<T>— основная реализация буфера (put,get,peek,clear,close,size,isEmpty,isFull).com.puchkov.BufferFullException— checked-исключение, бросаемое при попыткеputв переполненный буфер.com.puchkov.App— точка входаmain, запускающая два потока для демонстрации.
- JDK 8 или новее (используются
java.util.concurrent.atomicиReentrantLock). - Apache Maven 3.x для сборки и запуска.
- Подключение к интернету при первой сборке (для скачивания JUnit из Maven Central).
# 1. Клонирование репозитория
git clone <URL_репозитория>
cd RingBuffer
# 2. Сборка проекта (компиляция + тесты + jar)
mvn clean packageПосле сборки артефакт появится в директории target/:
target/RingBuffer-1.0-SNAPSHOT.jar
Проект не использует переменные окружения или внешние конфигурационные файлы. Поведение настраивается напрямую в коде — параметром конструктора RingBuffer(int capacity).
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
capacity |
int |
— (обязательный) | Ёмкость буфера. Должна быть строго больше нуля, иначе IllegalArgumentException. |
📝 TODO: при необходимости добавить файл
application.properties/.env.exampleс параметрами по умолчанию (например, размер буфера, уровень логирования).
# Компиляция
mvn compile
# Запуск через java напрямую (после mvn package)
java -cp target/RingBuffer-1.0-SNAPSHOT.jar com.puchkov.AppВ проекте нет HTTP/REST/GraphQL/gRPC endpoints — это библиотека, а не сервис. Ниже описано публичное API класса RingBuffer<T>.
| Сигнатура | Описание |
|---|---|
RingBuffer(int capacity) |
Создаёт буфер заданной ёмкости. Бросает IllegalArgumentException, если capacity <= 0. |
| Метод | Возвращает | Бросает | Описание |
|---|---|---|---|
put(T item) |
void |
InterruptedException, BufferFullException, NullPointerException |
Добавляет элемент в конец буфера. Бросает BufferFullException, если буфер заполнен; NullPointerException, если item == null. |
get() |
T |
InterruptedException |
Извлекает элемент с начала буфера. Возвращает null, если буфер пуст. |
peek() |
T |
InterruptedException |
Возвращает элемент с начала буфера без удаления. Возвращает null, если пусто. |
clear() |
void |
InterruptedException |
Удаляет все элементы и сбрасывает указатели. |
close() |
void |
— | Помечает буфер как закрытый и очищает его. После close() любая операция бросит IllegalStateException. |
size() |
int |
— | Текущее количество элементов в буфере. |
isEmpty() |
boolean |
IllegalStateException (если закрыт) |
true, если буфер пуст. |
isFull() |
boolean |
IllegalStateException (если закрыт) |
true, если буфер заполнен. |
toString() |
String |
— | Строковое представление содержимого в порядке от head к tail. |
Запускает два потока:
- Producer — кладёт в буфер 10 строк
"Item 0"…"Item 9". При полученииBufferFullExceptionждёт 100 мс и повторяет попытку. - Consumer — извлекает 10 элементов через
get().
| Исключение | Когда возникает |
|---|---|
IllegalArgumentException |
Конструктор вызван с capacity <= 0. |
NullPointerException |
put(null). |
BufferFullException |
put при заполненном буфере. |
InterruptedException |
Ожидание блокировки прервано. |
IllegalStateException |
Любая операция после close(). |
📝 TODO: документировать гарантии видимости и упорядоченности при многопоточной работе (memory model), добавить blocking-варианты
put/get(с ожиданием освобождения/появления места), вернуть осмысленное значение изget()в случае пустого буфера (например,Optional<T>).
Запуск тестов:
mvn testТекущее состояние:
- В каталоге
src/test/java/com/puchkov/есть только заготовкаAppTest.javaс тривиальной проверкойassertTrue(true)на JUnit 3.
📝 TODO: Добавить полноценные модульные и многопоточные тесты для
RingBuffer:
- корректность FIFO-порядка;
- проверка
BufferFullExceptionи реакции наput(null);- проверка
peek/clear/close;- стресс-тесты в нескольких producer/consumer-потоках (например, через
ExecutorServiceиCountDownLatch);- миграция тестов на JUnit 5.
- Добавить blocking-методы (
put/takeс ожиданием) аналогичноBlockingQueue. - Рассмотреть возврат
Optional<T>изget()/peek()вместоnull. - Зафиксировать в JavaDoc гарантии потокобезопасности и видимости.
- Подключить
exec-maven-pluginилиmaven-shade-pluginдля удобного запуска.