Concurrency Gotchas 3
* Visibility issues
No locking at all, or only intermittent locking. This is why "synchronized" on methods was trying to be done.
You need to synchronize when pulling out of a mutable data structure, even though things aren't being modified: another thread may be modifying it at the same time.
Double-checked locking is just a fail, because reads don't work. It can be fixed on the volatile field. The Holder Idiom (from "Effective Java" is better): put the instance as a final field on a inner static class.
Racy single check is okay -- processing a final value and storing the result into a field. Potential is for duplicated effort, but that's cheaper than synchronized. Important part is to copy the field into a local variable, check it/work on it/whatever, and then assign the field back to the variable.
Volatile arrays do not have volatile elements. Notably, the AtomicInteger array solves this.