полностью зависит от ваших потребностей.
В этом случае, помимо проблемы, первая из них неправильно защищает тест (если вы должны находиться внутри синхронизации или вы рискуете условиями гонки, когда кто-то другой изменит ее после того, как вы ее протестировали, но перед вами «мы закончили действовать по результатам теста), поэтому вы можете завершить два экземпляра - они, вероятно, эквивалентны после того, как JIT будет с ними выполнен.
В целом, однако, проблема с синхронизированными методами имеет тенденцию быть чрезмерно синхронизированной. Многие из них удерживают блокировку дольше, чем это абсолютно необходимо, и могут стоить вам производительности, заставляя другие потоки ждать дольше. Синхронизация должна выполняться в течение минимального времени, необходимого для того, чтобы сделать операцию атомой, и часто ее можно ограничить несколькими ключевыми строками, а не всем методом.
На другой руке ... иногда лучше не делать класс потокобезопасным вообще. Hashtables были потокобезопасными; HashMaps (более новая альтернатива) нет. Это связано с тем, что получение блокировки является относительно дорогостоящим процессом, особенно в многопроцессорных средах, и в реальном коде, если требуется потоковая безопасность, он обычно хочет покрыть больше, чем единственный доступ к хэш-карте, поэтому блокировка на этом уровне чаще всего расточительна, чем полезно.
http://en.wikipedia.org/wiki/Singleton_pattern Википедия объясняет гораздо лучше, чем где-либо еще – spiderman
Мое голосование за # 2 - причина, по которой проверка «null» выполняется в контексте синхронизированного блока ... Лучше решение будет заключаться в использовании 'enum' ... – MadProgrammer
Первый будет работать лучше. http://en.wikipedia.org/wiki/Double-checked_locking – anonymous