Search code examples
javacollectionsconcurrencyvolatilejava-memory-model

Using volatile collections and arrays in Java


Imagine we have

volatile int publisher = 0;
volatile List<String> list = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");
volatile String[] array = {"Buenos Aires", "Córdoba", "La Plata"};

As far as I understand.

Initial values in list and array are published correctly and are visible to all the reading threads.

All values added after the initialization are not safe-published.

Still we can read and publish them safely using

//in Thread 1
list.add("Safe City");
array[2] = "Safe city";
publisher = 1;

//in Thread2

if(publisher == 1) {
String city = list.get(3);
city = array[2];
}

Am I right?


Solution

  • That is correct, but...

    The volatile keyword on the list and array are irrelevant here - the fact that you write a value to the volatile publisher after you write the other values, and read back that value in your if condition before reading the other values in the second thread guarantees you memory consistency between those threads.

    If you remove the volatile keyword from the list and array, your code will still be safe.

    If you remove the publisher variable write/read, then the add operation* and array assignment are no longer safe.

    And yes, the initial assignment to the variables is also safe.

    * which is actually invalid on that particular list anyway as pointed out by Stuart Marks, but let's assume it's e.g. an ArrayList