iter
iter

Reputation: 4313

LinkedList queue and thread safety

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

Answers (2)

Nthalk
Nthalk

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

Voo
Voo

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

Related Questions