Ответ 1
Что делать, если вы создали класс, который форматирует даты с использованием пула фиксированных размеров для предварительно обработанных объектов SimpleDateFormat в циклическом режиме? Учитывая, что непротиворечивая синхронизация является дешевой, это может синхронизироваться на объекте SimpleDateFormat, амортизируя коллизии по всему набору.
Таким образом, может быть 50 форматировщиков, каждая из которых используется в свою очередь - столкновение и, следовательно, конфликт блокировки, произойдет только в том случае, если на самом деле было отформатировано 51 дат одновременно.
EDIT 2011-02-19 (PST)
Я реализовал фиксированный пул, как было предложено выше, код, для которого (включая тест), доступен на моем веб-сайте.
Ниже приведены результаты о четырехъядерном процессоре AMD Phenom II 965 BE, работающем в JVM Java 6 SE:
2011-02-19 15:28:13.039 : Threads=10, Iterations=1,000,000
2011-02-19 15:28:13.039 : Test 1:
2011-02-19 15:28:25.450 : Sync : 12,411 ms
2011-02-19 15:28:37.380 : Create : 10,862 ms
2011-02-19 15:28:42.673 : Clone : 4,221 ms
2011-02-19 15:28:47.842 : Pool : 4,097 ms
2011-02-19 15:28:48.915 : Test 2:
2011-02-19 15:29:00.099 : Sync : 11,184 ms
2011-02-19 15:29:11.685 : Create : 10,536 ms
2011-02-19 15:29:16.930 : Clone : 4,184 ms
2011-02-19 15:29:21.970 : Pool : 3,969 ms
2011-02-19 15:29:23.038 : Test 3:
2011-02-19 15:29:33.915 : Sync : 10,877 ms
2011-02-19 15:29:45.180 : Create : 10,195 ms
2011-02-19 15:29:50.320 : Clone : 4,067 ms
2011-02-19 15:29:55.403 : Pool : 4,013 ms
Примечательно, что клонирование и объединение были очень близки друг к другу. В повторных прогонах клонирование было быстрее, чем объединение, так часто, как это было медленнее. Разумеется, тест был специально разработан для экстремального соперничества.
В конкретном случае SimpleDateFormat, я думаю, у меня может возникнуть соблазн просто создать шаблон и клонировать его по требованию. В более общем случае у меня может возникнуть соблазн использовать этот пул для таких вещей.
Прежде чем принимать окончательное решение так или иначе, я бы хотел тщательно протестировать на различных JVM, версиях и для множества таких объектов. Старые JVM и устройства на небольших устройствах, таких как карманные компьютеры и телефоны, могут иметь гораздо больше накладных расходов при создании объектов и сборе мусора. И наоборот, у них может быть больше накладных расходов на неоспоримую синхронизацию.
FWIW, из моего обзора кода, казалось, что SimpleDateFormat, скорее всего, будет больше всего работать над клонированием.
EDIT 2011-02-19 (PST)
Также интересны необоснованные однопоточные результаты. В этом случае пул выполняется на одном уровне с одним синхронизированным объектом. Это будет означать, что пул является наилучшей альтернативой в целом, поскольку он обеспечивает отличную производительность, когда он доволен и когда он не работает. Немного удивительно, что клонирование менее полезно при однопоточности.
2011-02-20 13:26:58.169 : Threads=1, Iterations=10,000,000
2011-02-20 13:26:58.169 : Test 1:
2011-02-20 13:27:07.193 : Sync : 9,024 ms
2011-02-20 13:27:40.320 : Create : 32,060 ms
2011-02-20 13:27:53.777 : Clone : 12,388 ms
2011-02-20 13:28:02.286 : Pool : 7,440 ms
2011-02-20 13:28:03.354 : Test 2:
2011-02-20 13:28:10.777 : Sync : 7,423 ms
2011-02-20 13:28:43.774 : Create : 31,931 ms
2011-02-20 13:28:57.244 : Clone : 12,400 ms
2011-02-20 13:29:05.734 : Pool : 7,417 ms
2011-02-20 13:29:06.802 : Test 3:
2011-02-20 13:29:14.233 : Sync : 7,431 ms
2011-02-20 13:29:47.117 : Create : 31,816 ms
2011-02-20 13:30:00.567 : Clone : 12,382 ms
2011-02-20 13:30:09.079 : Pool : 7,444 ms