Rob Elliot
10/03/2022, 2:51 PMclass ConcurrentBuffer<T> {
private val lock = ReentrantReadWriteLock()
private val addLock = lock.readLock()
private val flushLock = lock.writeLock()
private var items = ConcurrentLinkedQueue<T>()
fun add(item: T) {
addLock.withLock {
items.add(item)
}
}
fun flush(): Collection<T> {
return flushLock.withLock {
val flushed = items.toList()
items = ConcurrentLinkedQueue()
flushed
}
}
}
Joffrey
10/08/2022, 10:35 AMChannel
?Joffrey
10/08/2022, 10:35 AMRob Elliot
10/08/2022, 10:40 AMChannel
.
It's not immediately clear to me how a Channel
would replace that structure... the atomic flushing is the most important aspect of it. But perhaps I need to read and think more.Rob Elliot
10/08/2022, 10:42 AMadd
and flush
methods (or equivalent) then I'd consider putting coroutines in, but if I've still got to write the flush
method and make it atomic then I don't see a vast amount of value over java concurrency structures. I'm sort of half hoping Loom saves me from really having to get into coroutines.Joffrey
10/08/2022, 11:55 AMthen I don't see a vast amount of value over java concurrency structuresYou asked for something non-blocking, which is not delivered by lock-based approaches like this
Rob Elliot
10/08/2022, 11:58 AMadd
, not the flush
. I'm under the impression that java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock
is non-blocking unless something is trying to use its WriteLock
pair, and ConcurrentLinkedQueue
is non blocking.Joffrey
10/08/2022, 11:59 AMthe atomic flushing is the most important aspect of itI see. What is the use case of it by the way? For instance, why does the consumer flush from time to time instead of processing things as they come? I didn't realize the flushing needed to be "atomic" (not sure what you mean by that in this context). You want producers to suspend when sending items to this structure while the flush happens, and the flush should only consider items that were already sent at the moment it started? Or is it less constrained than that?
Joffrey
10/08/2022, 12:02 PMIt's not immediately clear to me how awould replace that structureChannel
Channels are naturally thread-safe, multi-producers, and multi-consumers. An easy-ish approach to this with a
Channel
would be that you have your producers sending items to the channel, and then when you want the flush to happen you can send a sentinel value to the channel and start a consumer that would pop all values until the sentinel (and drop the sentinel). This way, producers can even keep sending to the channel.Joffrey
10/08/2022, 12:02 PMRob Elliot
10/08/2022, 12:03 PMRob Elliot
10/08/2022, 12:07 PMJoffrey
10/08/2022, 12:11 PMJoffrey
10/08/2022, 12:18 PMRob Elliot
10/08/2022, 1:40 PM