Próbuję użyć zarówno InheritableThreadLocal
i ThreadPoolExecutor
.Korzystanie z InheritableThreadLocal z ThreadPoolExecutor - lub - ThreadPoolExecutor, który nie używa ponownie wątków
Dzieli się, ponieważ ThreadPoolExecutor
ponownie wykorzystuje wątki dla każdej puli (w końcu jest to pula), co oznacza, że InheritableThreadLocal
nie działa zgodnie z oczekiwaniami. Teraz problem wydaje mi się oczywisty, ale szczególnie trudna do wyśledzenia.
Używam InheritableThreadLocal
, więc każdy z kilku procesów najwyższego poziomu ma własne połączenie z bazą danych dla siebie i wszelkich podprocesów, które spawns. Nie używam tylko jednej wspólnej puli połączeń, ponieważ każdy proces na najwyższym poziomie będzie wykonywał wiele wieloetapowych prac związanych z połączeniem przed przystąpieniem do bazy danych i/lub przygotowaniem wielu gotowych zestawów, które są używane w kółko.
Używam wspólnego ThreadPoolExecutor
między tymi procesami najwyższego poziomu, ponieważ istnieją pewne zachowania, które muszą być bramkowane. na przykład Mimo że mogę uruchomić 4 procesy najwyższego poziomu, mogę mieć tylko jeden proces zapisujący dane do bazy danych na raz (lub system musi przejść do innego udostępnionego zasobu). Tak więc będę miał proces najwyższego poziomu, który utworzy Runnable
i wyśle go do współużytkowanego ThreadPoolExecutor
, aby upewnić się, że nie więcej niż jeden (lub dwa lub trzy w zależności od przypadku) są uruchomione w tym samym czasie w całym systemie.
Problem polega na tym, że ponieważ ThreadPoolExecutor
ponownie używa wątków dla pul, InheritableThreadLocal
pobiera początkową wartość, która została uruchomiona w tej puli, zamiast wartości, która była w procesie najwyższego poziomu, który wysłał Runnable do ThreadPoolExecutor
.
Czy istnieje jakiś sposób, aby wymusić na basen pracownikiem w
ThreadPoolExecutor
użyć wartościInheritableThreadLocal
że był w kontekście procesu, które utworzyły Runnable zamiast w kontekście ponownego wykorzystania puli wątków?Czy istnieje implementacja
ThreadPoolExecutor
, która tworzy nowy wątek za każdym razem, gdy rozpoczyna nowy program Runnable? Dla moich celów zależy mi tylko na bramkowaniu liczby jednocześnie działających wątków do ustalonego rozmiaru.Czy istnieją inne rozwiązania lub sugestie, które ludzie mają dla mnie, aby osiągnąć to, co opisałem powyżej?
(Choć zdaję sobie sprawę, mogę rozwiązać ten problem przez przepuszczenie całego połączenia z bazą danych z klasy do klasy podwątku do podwątku jak pewnego rodzaju wspólnoty rowerze, chciałbym tego uniknąć).
Istnieje również poprzednie pytanie dotyczące StackOverflow, InheritableThreadLocal and thread pools, które rozwiązuje również ten problem. Jednak rozwiązanie tego problemu wydaje się, że jest to kiepski przypadek użycia dla InheritableThreadLocal, który moim zdaniem nie dotyczy mojej sytuacji.
Dzięki za wszelkie pomysły.
Nie użyłem Semaforów, więc przyjrzę się temu. Używamy wielu innych funkcji Executorów (Futures, timeout itp.), Ale jest to możliwe, że mogę to zrobić z Semaforami lub że mogę użyć zwykłego executora (nie puli wątków) oraz semaforów, aby uzyskać wszystko, czego potrzebuję. Dzięki. –
To była właściwa droga. Używanie Semaphores i FutureTasks było bardziej reprezentatywnym paradygmatem tego, co chcieliśmy zrobić. Po zmianie kod został znacznie uproszczony, co zawsze jest dobrym znakiem. Dodatkowo rozwiązało wszelkie problemy z InheritableThreadLocal. –