I am no Java programmer, but as a real-time programmer I think both of your implementations are conceptually wrong.
I might have misunderstood how Java synchronization works, though. In that case, please disregard this post and accept my apologies.
Your first solution
makes sure there is no concurrency between writers because you lock the access to the only function that allows to modify one element.
You also lock access to the array as a whole, but only between readers (which is useless since the readers will not modify the data, and thus could safely read the array concurrently).
However, you do not prevent concurrent access between readers and writers. It is possible that one (single) reader reads the value of an element that is being modified by a (single) writer.
Besides, you return a reference to your member array instead of a copy, so the caller will access the actual data that are likely to be overwritten at any time by the writers.
As a consequence, the array is not protected at all against read accesses during writes, even after you called your read accessor.
The code might work if for some reason the actual access to an element of the array is atomic (which I very doubt, but again Java is not my cup of tea) or more likely because potential inconsistencies are rare and not easily detectable. Your application could go haywire if you run on a different environment or even change your code slightly so that it increases the occurences of concurrent read/writes or becomes more vulnerable to these inconsistencies.
Your second solution
uses the AtomicArray, that does the same as your precedent code, but adds a protection to concurrent reads on a single array value.
It gets rid of the potential inconstistencies of the first solution (also because this time your reader function is forced to return a copy of the actual array), but reading the whole array is terribly inefficient, because your AtomicArray object will take and release the lock for each value read.
A possible approach
What you must protect is the array as a whole.
In a general case, you might want to use a reader/writer lock. That would allow multiple readers to access the array concurrently.
However, if I understood correctly, in your case there is only one reader, so better use a simple lock.
The code for your single write and global read would be as follows:
public final class SynchronizedIntArray {
private final int[] elements = new int[1000000];
private final Lock lock = new ReentrantLock();
public void set(int index, int value)
{
lock.lock();
elements[index] = value;
lock.unlock();
}
public int[] getAll()
{
int[] copy;
lock.lock();
copy = elements.clone();
lock.unlock();
return copy;
}
}