No, the code is not thread-safe. It may or may not throw a ConcurrentModificationException
, but you may end up with elements missing or elements being added twice. Changing the list to be a
Collection<String> FILES = Collections.synchronizedList(new ArrayList<String>());
might already be a solution, assuming that the most time-consuming part is the getFilesAsList
method (and not adding the resulting elements to the FILES
list).
BTW, an aside: When getFileAsList
is accessing the hard-drive, you should perform detailed performance tests. Multi-threaded hard-drive accesses may be slower than a single-threaded one, because the hard drive head might have to jump around the drive and not be able to read data as a contiguous block.
EDIT: In response to the comment: This program will "very likely" produce ArrayIndexOutOfBoundsExceptions
from time to time:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class ConcurrentListTest
{
public static void main(String[] args) throws InterruptedException
{
for (int i=0; i<1000; i++)
{
runTest();
}
}
private static void runTest() throws InterruptedException
{
final Collection<String> FILES = new ArrayList<String>(1);
// With this, it will always work:
// final Collection<String> FILES = Collections.synchronizedList(new ArrayList<String>(1));
List<String> list = Arrays.asList("A", "B", "C", "D");
List<Thread> threads = new ArrayList<Thread>();
for (final String s : list)
{
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
List<String> file2List = getFileAsList(s);
FILES.addAll(file2List);
}
});
threads.add(thread);
thread.start();
}
for (Thread thread : threads)
{
thread.join();
}
System.out.println(FILES.size());
}
private static List<String> getFileAsList(String s)
{
List<String> list = Collections.nCopies(10000, s);
return list;
}
}
But of course, there is no strict guarantee that it will. If it does not create such an exception for you, you should consider playing the lottery, because you must be remarkably lucky.