§Используйте ленивую инициализацию избирательно
В большинстве случаев, нормальная инициализация предпочтительнее, чем ленивая. Если вы используете ленивую инициализацию для избавления от многократной инициализации, делайте это в синхронизованном вызове
Если вам нужно применить подход ленивой инициализации и синхронной инициализации к static переменной – это называется владелец ленивой инициализации. Мы получаем бесплатно синхронизированную инициализацию класса при первом обращении, и оптимизированные последующие обращения.
Если необходимо использовать ленивую инициализацию для производительной инициализации поля класса, используйте подход двойной проверки.
Если поле допускает многократную инициализацию, то возможно использовать одинарную проверку Если вы допускаете, что каждый поток проинициализирует это поле, и тип поля не long и не double, то можете убирать модификатор volatile.
§72 Не завязывайтесь на работу планировщика
Любая программа, которая полагается на определенную работу планировщика в своей работе или для обеспечения производительности – почти наверняка не портируема. Количество runnable потоков должно не сильно превосходить количество ядер. (waiting runnable)
Поток не должен быть запущен до тех пор, пока он не может сделать что-то полезное. Потоки не должны в цикле проверять что-то для продолжения своей работы (busy-wait)
Класс будет работать в 2000 раз медленнее чем CountDownLatch при 1000 потоков
Попытка исправить подобные проблемы при помощи Thread.yield() - не удачная альтернатива Thread.yield() не обладает тестируемой семантикой Приоритет потоков облает наименьшей переносимостью из JDK Thread groups are obsolete