Java – Sharing buffer between multiple threads

iojavamultithreading

I had a job process that was executing a lot of IO to read and write temporary files.
Now I want to (need to) reduce the quantity of IO executions.

So I want to create a sort of circular buffer that is going to be filled up with a data from a text file within first thread.

The consumer (reading) thread will fetch data from this buffer.

The problem is that there could be multiple consumers that need to read from same one buffer.

For buffer implementation I prefer not to use any existing wrappers (simple array, where i just "play" with indices is enough).

I also don't want to create a separate buffer for every reader.
And ofcourse I want to avoid any deadlocks and unnecessary blockings.

UPDATE
Right now I am using circular buffer (an array and 2 indices)

The question is how to implement such buffer that can be accessed by multiple consumers where each consumer can read from it interdependently from other consumers (one costumer may read faster than the other one).

IMPORTANT UPDATE
The first thread don't know (and should not know) about it's consumers!!!
It should write data to a buffer, when data ends it should raise a flag.

Best Answer

Using a bare array is forcing you to do more work than you need to. People have spent a lot of time coming up with data structures to make your life easier, so use them.

It sounds like you are trying to implement a Queue. This is a data structure that allows you to add things to the collection and then remove them later. This is done in a first in first out order. Java even has a Thread-Safe Queue built in. You can simply make an instance of that class and give each of your threads a reference to it. The producer will add items to the queue and the consumer(s) will remove items from the queue or perform another action if the queue is empty.

If you really have your heart set on implementing everything yourself, you will need to synchronize all access to your array so that two threads can't access the buffer at the same time.

EDIT:

It wasn't clear before that you wanted every consumer to read every bit of data. You can extend the Queue implementation so it keeps track of the count of items (making size() constant time) and then throw an exception if the queue is full.

To solve the popping issue is a little trickier. You need to keep track of the index that each consumer is at, a map would do this. Then when all of the consumers have moved passed an item, it can be popped and update all the indexes in the map. When a consumer calls pop() and the item needs to be retained you can re-route it to a peek().

Related Topic