Существуют ли какие-либо реализации пула потоков (в Java), которые обеспечивают выполнение всех задач для одного и того же логического идентификатора в одном и том же потоке?
Логика, за которой я пришел, - это если в конкретном потоке для данного логического идентификатора уже выполняется задача, тогда новые задачи с тем же идентификатором запланированы в том же потоке. Если нет потоков, выполняющих задачу для одного и того же идентификатора, тогда можно использовать любой поток.
Это позволит выполнять параллельные задачи для несвязанных идентификаторов, но задачи для того же ID, которые будут выполняться последовательно и в представленном порядке.
Если нет, есть ли предложения о том, как я могу расширить ThreadPoolExecutor
, чтобы получить это поведение (если это возможно)?
UPDATE
Проведя больше размышлений об этом, я фактически не требую, чтобы задачи для одного и того же логического идентификатора выполнялись в одном потоке, просто они не выполнялись одновременно.
Примером для этого может служить система, которая обрабатывала заказы для клиентов, где было нормально обрабатывать несколько заказов одновременно, но не для одного и того же клиента (и все заказы для одного и того же клиента должны были обрабатываться в порядке).
Подход, который я принимаю на данный момент, - это использовать стандартный ThreadPoolExecutor с настраиваемым BlockingQueue
, а также обернуть Runnable
с помощью специальной оболочки. Логика оболочки Runnable
:
- Атомно попытайтесь добавить идентификатор к параллельному "запущенному" набору (
ConcurrentHashMap
), чтобы увидеть, запущена ли задача для того же ID- Если сбой добавления, нажмите задачу обратно на переднюю часть очереди и немедленно верните
- если выполняется, продолжайте
- Запустить задачу
- Удалите связанный с задачей идентификатор из набора "running"
Методы очереди poll()
затем возвращают только те задачи, у которых есть идентификатор, который в настоящее время не находится в "запущенном" наборе.
Проблема заключается в том, что я уверен, что будет много угловых случаев, о которых я не думал, поэтому потребуется много испытаний.