I need to spawn N consumer threads, which process same InputStream concurrently, e.g - transform it somehow, calculate checksum or digital signature etc. These consumers do not
The way I see it, you should have at least some kind of buffering so different consumers can move through the stream at different pace without everything being constantly bogged down by the currently slowest consumer. That basically ensures worst-case performance and very little benefit of concurrency.
You could, say, tag each chunk with the consumers that have used it so far and then delete those that are completely used up. Maybe this could be achieved by each consumer holding a reference to each chunk it hasn't yet used, which would allow GC to automatically take care of used chunks. The producer might keep a list of WeakReference
s to the chunks so it has a handle on the number of chunks yet to be used and base its throttling on that.
I am also thinking about having a separate InputStream
instance per thread, which internally communicates with the producer InputStream
. This way you have an easy solution for your livelock hazard: try ... finally { is.close(); }
-- the dying consumer closes its own inputstream. This is communicated to the producer.
I have some ideas with using an ArrayBlockingQueue
per consumer. There would be some difficulty in ensuring that all consumers are properly fed, without making the producer either block or busy-wait.