Бьюсь об заклад, вы слишком оптимистичны. Размер пакета в один миллион означает, что вы попадаете в БД при каждой миллионной вставке. Если бы вы использовали тысячу вместо этого, вы бы не увидели разницы в производительности и потратили бы гораздо меньше идентификаторов. Конечно, с long
это не имеет большого значения.
Выполнение вышеуказанного в каждом потоке означает, что вы тратите до миллиона идентификаторов на каждый поток. Ничего страшного с long
, я знаю.
Это также увеличит стоимость запуска без необходимости и, возможно, оставит много локального мусора. Опять же, ничего страшного, но в чем преимущество? Короткий код, подобный приведенному выше, занимает несколько наносекунд, а доступ к БД занимает на много порядков больше. Таким образом, никакие разногласия не могли бы действительно замедлить вас.
Однако правильный способ оптимизировать это, вероятно, через AtomicLong
. Это имеет намного меньшую нагрузку, чем синхронизация. Используйте getAndIncrement
и введите синхронизированный блок только тогда, когда вы переполните свой nextFetchId
. В этом блоке сначала перепроверьте, выполнил ли другой поток работу, которую вы собираетесь выполнить, и если нет, получите следующий идентификатор из базы данных.
Намного проще использовать спящий режим HiLoOptimizer
или его лучший вариант.