Использование InheritableThreadLocal с ThreadPoolExecutor - или - ThreadPoolExecutor, который не использует повторно потоки

Я пытаюсь использовать как InheritableThreadLocal , так и ThreadPoolExecutor .

Это не работает, потому что ThreadPoolExecutor повторно использует потоки для каждого пула (в конце концов, это пул), то есть InheritableThreadLocal не работает должным образом. Теперь проблема кажется мне очевидной, но выследить ее было особенно сложно.

Я использую InheritableThreadLocal , чтобы каждый из нескольких процессов верхнего уровня имел собственное соединение с базой данных для себя и любых подпроцессов, которые он порождает. Я не просто использую один общий пул соединений, потому что каждый процесс верхнего уровня будет выполнять много многоэтапной работы со своим соединением перед фиксацией в базе данных и / или подготовкой множества PreparedStatements, которые используются снова и снова.

Я использую общий ThreadPoolExecutor между этими процессами верхнего уровня, потому что есть определенные поведения, которые необходимо заблокировать. например Несмотря на то, что у меня может быть запущено 4 процесса верхнего уровня, у меня может быть только один процесс, записывающий в базу данных за раз (или системе необходимо подключиться к другому общему ресурсу).Итак, я прикажу процессу верхнего уровня создать Runnable и отправить его в общий ThreadPoolExecutor , чтобы убедиться, что не более одного (или двух или трех, в зависимости от случая) ) работают одновременно во всей системе.

Проблема в том, что поскольку ThreadPoolExecutor повторно использует свои потоки для пулов, InheritableThreadLocal забирает исходное значение, которое было запущено в этом пуле, а не значение, которое было в процесс верхнего уровня, который отправил Runnable ThreadPoolExecutor .

  • Есть ли способ заставить рабочий пул в ThreadPoolExecutor использовать значение InheritableThreadLocal , которое было в контексте процесса, создавшего Runnable, а не в контексте повторно используемый пул потоков?

  • В качестве альтернативы, существует ли какая-либо реализация ThreadPoolExecutor , которая создает новый поток каждый раз, когда он запускает новый Runnable? Для моих целей меня интересует только ограничение количества одновременно работающих потоков до фиксированного размера.

  • Есть ли у людей какие-либо другие решения или предложения, чтобы я мог выполнить то, что я описал выше?

(Хотя я понимаю, что могу решить проблему, передав соединение с базой данных от класса к классу, чтобы подпоток к подпотоку, например своего рода общественный велосипед, я бы хотел избежать этого.)

Есть предыдущий вопрос по StackOverflow, InheritableThreadLocal и пулам потоков , который также решает эту проблему.Однако решение этой проблемы, по-видимому, заключается в том, что InheritableThreadLocal плохо подходит для использования, что, по моему мнению, не применимо к моей ситуации.

Спасибо за любые идеи.

17
задан Benjamin W. 4 November 2017 в 05:09
поделиться