As volatile only applies to variable reference, is there anyway to make write(add) to List from one thread to be visible to another thread?
My code has two threads, one thread A pushes a lot of items to a List, another thread B reads the List after thread A finishes; two threads are synced by CountDownLatch. It happens several times when thread B read the List, not all items in List are visible.
My code looks like (the actual code is more complicated than this, the below code is too simple to reproduce the issue):
public class TestList {
@Test
public void test() throws InterruptedException {
int num = 1000;
final CountDownLatch latch = new CountDownLatch(1000);
final List<Integer> list = new ArrayList<Integer>();
for (int i=0; i<num; i++) {
final int finalI = i;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
list.add(finalI);
latch.countDown();
}
});
t.start();
}
latch.await(1, TimeUnit.MINUTES);
System.out.println(list.size());
}
}
UPDATE: thanks for all answers. As @MikeStrobel's statement, I finally realize it's not only a memory visibility issue but also a synchronization issue. So the solution should be Collections#synchronizedList(...) as Kevin said, or synchronized keyword