am I right to assume this would fail due to the fact that the helper == null check in the synchronized block has a chance to fail because it could be "partially" constructed at that point?
Yes you are right. This is explained in Out-of-order writes. helper = new Helper()
consists of 3 steps: memory allocation, call to the constructor, and assignment. JIT compiler is free to reorder instructions and do assignment after memory allocation (which returns reference to the new object) but before the constructor invocation. Using volatile prevents reordering.