Reputation: 4313
I have one thread that add()
s objects into a LinkedList queue, and another thread that poll()
s the queue for objects to process. These re the only two methods I use on my queue. I never iterate through the queue, nor add nor remove objects in the middle of the list. I cannot think of a scenario when the two threads step on each other and corrupt the data somehow, but perhaps my imagination is simply lacking.
The pushing is infrequent (several times per second) but the polling is very frequent (a couple thousand times per second). I wonder how much of a penalty I get for synchronizing the add()
and the poll()
. This is running on Android.
Edit: I am not looking for a BlockingQueue
; I am blocking on I/O, not on objects in the queue:
The run()
method on the polling thread blocks waiting for space to become available in an output buffer. When space becomes available, it looks to see if it has any objects waiting on the queue. If one is available, it serializes it into the output buffer. If the queue is empty (i.e. poll()
returns null
), it poll()
s other, lower-priority queues, and if all are empty, serializes a "no data available now" message.
Upvotes: 0
Views: 4546
Reputation: 3833
Without synchronization, you may get the case where the reading thread is polling the an object that has JUST been added to the queue, and that the list has not quite finished exiting out of the add() method.
If you look into the source, it's possible to screw something up with "expectedModCount = l.modCount;" because the latch for the poll is based on a line below it before modCount is actually modified.
Essentially, your remove is happening at the perfect time, probably with 1 element, while adding another at the same time, and getting something wrong.
To prevent this, you can wrap your accesses in synchronized(lst){} blocks or you can use the concurrent classes. I would prefer the concurrent queues because poll doesn't have to spin -- you can have a blocking take().
You're probably looking for: java.util.concurrent.ArrayBlockingQueue
ArrayBlockingQueue<String> que = new ArrayBlockingQueue<String>(100);
que.add("");
que.take();
Upvotes: 2
Reputation: 30245
Umn doesn't android have BlockingQueues? They are designed for exactly that scenario, no idea why you'd want to use anything else - can't get much more efficient..
Upvotes: 5