Думаю решений может быть несколько.
1 - блоки synchronized с wait/notify[All]. Обработчик встал на wait, накопитель пашет, как закончил, встает делает notifyAll и встает на sleep. далее аналогично.
Проблемы: трудно масштабировать, notifyAll будет будить все ждущие потоки и если добавится ещё, то просыпаться будут все и жрать буфер будут все.
2 - Аналогичное решение c Lock-ами.
3 - Очередь, Один поток пишет в очередь, другой читает из неё, наверняка можно завернуть в очередь буфферизированный поток или навернуть свой буффер вокруг этой очереди. Плюсы - легко реализовать, синхронизация из коробки. Минусы - масштабирование - не ясно как читать из очереди чанки из буффера множеством потоков, чтобы потом выдать результат в нужном порядке.
4 - пул потоков обработчиков. Это решение нужно для более простого масштабирования, возможно вам не подойдет. Делаете пул потоков, который умеет обрабатывать определенный класс буффера. Накопитель по готовности скармливает буффер готовому потоку из пула просто запуская этот thread.