Я думаю, что у меня есть ответ после того, как я подумал:
ПРИМЕЧАНИЕ: мой ответ зависит от того факта, что фабрика идемпотентна по отношению к его ключу String, а рабочие все идемпотентны относительно своей фабрики, что можетне было очевидно из вопроса.
Для первой глобальной хэш-карты на основе одноэлементного ключа я использую идею о том, что хэш-карта никогда не имеет удалений.Только новые идемпотентные.Поэтому я использую volatile ссылку на hashmap и получаю текущую карту из переменной volatile singleton без мьютекса.(изменчивые выборки ссылок в Java теперь очень дешевы). Если карта устарела, в том смысле, что в ней нет всех существующих фабрик, это нормально.Потому что, если у него есть фабрика (обычно она разогревается), я ее получу.Только стоимость летучих получить.Если у него его нет, я сейчас сверяюсь с живой картой, чтобы получить доступ к мьютексу для «живой» карты.Если я получу фабрику с карты сейчас (маловероятно), я получу ее.В противном случае, я сейчас делаю очень дорогую операцию по созданию фабрики (вне мьютексов).Когда я закончил, я вернулся к живой карте с мьютексом, и из-за того, что другой поток делал то же самое, он может быть там сейчас!Так что, если на карте есть фабрика, я выбрасываю потраченную впустую фабрику и использую ту, которая была поставлена передо мной.В противном случае я добавляю новую фабрику на карту, оставляю мьютекс и начинаю использовать фабрику.
Не думаю, что для этого есть что-то лучше.
На заводской софт-кеш, я думаюЯ просто хочу использовать ConcurrentLinkedQueue.Тем не менее, мои элементы будут ссылками на softreferences.Поэтому я извлекаю из ConcurrentLinkedQueue объект, который имеет ссылку на мягкую ссылку на самого работника.Возможно, рабочий был освобожден, поэтому я просто снова создаю рабочий на фабрике, воссоздаю мягкую ссылку в объекте, полученном из ConcurrentLinkedQueue, и устанавливаю мягкую ссылку на рабочего.Так что нет никакого мьютекса для получения работника с завода, только извлечение ConcurrentLinkedQueue, и ссылки на работника мягкие.