Eu gostaria de salientar que seu singleton # 3, que ele marcou “errado”, está correto (porque o bloqueio implica automaticamente uma barreira de memory na saída ). Ele também deve ser mais rápido que o singleton # 2 quando você usa a instância mais de uma vez (que é mais ou menos o ponto de um singleton :-)). Então, se você realmente precisa de uma implementação preguiçosa de singletons, eu provavelmente escolheria essa – pelas simples razões que (1) é muito claro para todos que lêem o seu código o que está acontecendo e (2) você sabe o que vai acontecer com exceções.
Caso você esteja se perguntando: eu nunca usaria singleton # 6 porque ele pode facilmente levar a deadlocks e comportamentos inesperados com exceções. Para mais detalhes, consulte: modo de bloqueio do lazy , especificamente ExecutionAndPublication.