I have a volatile reference to an immutable array that is changed asynchronously by replacing the reference with a new version. Is it guaranteed to be thread-safe when iterating with foreach over this array?
Example:
class MyClass
{
volatile String[] m_array = new String[0];
public synchronized void add(String n)
{ m_array = ArrayUtils.add(m_array, n); // atomic replace
}
public void iterate() // not synchronized!
{ // Do something with each element
for (String s : m_array)
System.out.println(s);
}
}
Why I ask this Question?
Normally the foreach loop in Java expands to an Iterator
:
Iterator<String> i = m_array.iterator();
while(i.hasNext())
...
In this case there is only one access to m_array effectively taking an atomic snapshot. So everything is fine.
But what if a future Java implementation optimizes foreach for raw arrays because iterators are quite slow in this case? (see foreach vs. for performance)
The implementation might generate code like
for (int i = 0; i < m_array.length; i++)
{ String s = m_array[i];
...
This is no longer thread-safe, because of multiple accesses to m_array
.
In this case a temporary variable with a snapshot of m_array
is required when the field is volatile.
Is the above optimization guaranteed never to happen in this way and my code example guaranteed to be safe?