0

this is a follow-up post to Do I need a concurrent collection for adding elements to a list by many threads?

everybody there has focused on expaning of the list. I understand how that can be a problem, but .. what about adding elements ? is that thread-safe?

example code

static final Collection<String> FILES = new ArrayList<String>(1000000);

and I execute in many threads (I add less than 1000000 elements)

FILES.add(string)

is that thread safe ? what are possible problems with doing it that way ?

Community
  • 1
  • 1
IAdapter
  • 62,595
  • 73
  • 179
  • 242
  • No. ArrayList is not threadSafe. Use Collections.synchronizedList(new ArrayList()); . refer http://stackoverflow.com/questions/11360401/java-synchronized-list – TheLostMind Mar 20 '14 at 09:36
  • I explained it in my post. What do you still not understand? At the moment when your add operation is performed you can simply have different results. Read again my post that you are reffering to and try to ask me more precisely what you dont understand in that explanation and what is missing. – RMachnik Mar 20 '14 at 09:40
  • I think that I made right answer for your first question. So you simply can delete that question. I made some updates in first one so it might more precisely explain it. – RMachnik Mar 20 '14 at 09:46

4 Answers4

1

ArrayList<String> is not synchronized by itself. Use Collections.synchronizedList(new ArrayList<String>()) instead.

Harmlezz
  • 7,972
  • 27
  • 35
  • That will synchronize the entire list (including read operations). Not recommended for code that must be efficient. I would recommend the explicit use of an [ReentrantReadWriteLock](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html) instead. – Martin Andersson Mar 20 '14 at 09:46
  • If random access is not a requirement, I'd go with a [ConcurrentLinkedQueue](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html) or [ConcurrentLinkedDeque](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedDeque.html). – Martin Andersson Mar 20 '14 at 09:53
0

use Collections.syncronizedList(new ArrayList<String>(1000000))

Autocrab
  • 3,474
  • 1
  • 15
  • 15
0

Even if the list doesn't expand, it maintains its internal state, such as the current size. In a wider sense, ArrayList is specified a mutable object which is not thread-safe, therefore it is illegal to concurrently call any mutator methods on it.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
0
public boolean add(E e) {
     ensureCapacityInternal(size + 1);  // Increments modCount!!
     elementData[size++] = e;
     return true;
}

This is the source cod of the ArrayList in 7u40-b43. The method ensureCapacityInternal() is not thread safe,and size++ is not either. The size++ is done by three steps,1)get the size,2) size +1,3) write the new value back.

kali
  • 31
  • 3