-
Notifications
You must be signed in to change notification settings - Fork 401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-linearizable behavior of concurrent queues #216
Comments
Thanks @alefedor this is a interesting test. The behaviour is related to why For an overall system to make good progress it is better not to spin on a condition more than necessary which can starve out other threads which could be making progress. We will need to ponder this and consider how we improve the documentation to make it expectations more clear. I believe there is a failing in the Java All this being said thanks for raising the issue and the tool looks interesting. |
Hi @mjpt777! Is that true that in order to reduce contention |
@mjpt777, if these data structures are relaxed, then this behavior is fine, but it probably should have been described either in the documentation or even in the name. Anyway, thank you for your detailed reply! |
@ndkoval In this implementation that is correct. If the thread doing the In a realistic system it is not natural for a producer to immediately try to consume what it just produced. While it is possible to implement a queue that supports this the cost of doing so is high for an unnatural requirement. |
@alefedor You are right to suggest the documentation could be improved and we will take that onboard. |
Totally agree with @mjpt777 : on JCTools we have chosen to impl a relaxedPoll API to overcome the limitations of the Java Queue API for this same reason. |
Appreciate that this has been closed for a while but it seemed the most apt place to comment. I am using
it sometimes throws a |
While I think it would be possible make this work for your specific case and the ManyToOne queue, I think it is the wrong approach to take. With concurrent structures, like a concurrent queue, it is not safe to assume that the data will be consistent across independent method calls. The two operations will not represent one atomic action. The far safer option is to just assume that
This code will always be safe and achieves the same thing and will likely be just as efficient (if not faster). Were you to change this to a ManyToMany queue and had other threads consuming messages as well, the code would still continue to work correctly, where as relying on the isEmpty check would be broken in that scenario. |
Thanks @mikeb01. Checking for |
@itsmemrbump The JDK Queue interface is a very bad design for a concurrent queue. As a general rule, and @mikeb01 points this out, that concurrent access is only consistent within the context of a single method call. The world can have changed between calls in an concurrent context. It is best to design and implement with this in mind. |
There is a bug in
ManyToManyConcurrentArrayQueue
,ManyToOneConcurrentArrayQueue
andManyToOneConcurrentLinkedQueue
that leads topoll
returningnull
even if there was anoffer
operation before in the same thread and there are no concurrentpoll
operations.I believe that this bug differs from the one mentioned in documentation, because it is not connected to
isEmpty
orsize
methods and queues are known to be not empty.The bug can be reproduced with Lincheck.
The scenario that can produce non-linearizable results is the same for all mentioned queues:
There are two parallel threads and the
poll
operation in the second thread returnsnull
despite the fact that the queue definitely contains at least one element (the element that was added by the previousoffer(5)
).Here is an example of incorrect execution for
ManyToOneConcurrentLinkedQueue
(yet to be released feature in Lincheck):The text was updated successfully, but these errors were encountered: