Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections.synchronizedlist() remove element while iterating from end [duplicate]

Tags:

I am using Collections.Synchronizedlist() to make my arraylist thread safe. What I want to ask is the following code thread-safe i.e. remove while iterating over list from the end:-

pendingExecutionList = Collections.synchronizedList(new ArrayList<>(initialCapacity));

I am creating the list in main thread. and adding to this list from different threads. But, iteration and removal is being done only from a single Scheduled thread as shown below:-

for (int i = pendingExecutionList.size() - 1; i >= 0; i--) 
{
   if (someCondition(pendingExecutionList.get(i))) 
   {
      process(pendingExecutionList.remove(i));
   }
}

The above code is executed by only a single thread while multiple threads are adding to this list.

I want to avoid using iterator over synchronized(list) as that is not fail-safe.

like image 658
maveroid Avatar asked Apr 18 '16 08:04

maveroid


2 Answers

Instead holding the lock, you are actually obtaining the lock once per element. This has a risk of being slower than just holding the lock while you do your check.

I suggest you consider using a PriorityQueue with an appropriate ordering. This will order the queue so the ones you are about to process next will be at the start and the cost of removal is relatively cheap regardless of the number of waiting tasks.

like image 115
Peter Lawrey Avatar answered Sep 28 '22 04:09

Peter Lawrey


If I'm understanding correctly your workflow pipeline, I would suggest trying some variant of a BlockingQueue instead of a synchronizedList().

ArrayBlockingQueue would allow you to have fair scheduling of the executions and should keep the caches of the multiple producers fairly hot (unless your producers start overtaking the cache prefetcher, in which case you'll experience false sharing).

If you are in the mood for experimenting, you can take a look at the MPSC (multiple producers, single consumer) queues available outside of the JDK, like Nitsan Wakart's MpscArrayQueue or the Disruptor.

like image 33
Dimitar Dimitrov Avatar answered Sep 28 '22 04:09

Dimitar Dimitrov