2010-07-19 9 views
29

Executors zapewnia newCachedThreadPool() i newScheduledThreadPool(), ale nie newCachedScheduledThreadPool(), co daje tutaj? Mam aplikację, która otrzymuje wiadomości masowe i musi zaplanować dość długi etap przetwarzania po ustalonym opóźnieniu dla każdego. Ograniczenia czasowe nie są super ścisłe, ale wolałbym, aby więcej wątków zostało utworzonych w locie, jeśli przekroczę rozmiar puli, a następnie będę je przycinał podczas okresów braku aktywności. Czy jest coś, co przegapiłem w równoległej bibliotece, czy muszę napisać własną?Dlaczego nie ma zaplanowanej buforowanej puli wątków dostarczanej przez klasę Java Executors?

Odpowiedz

3

java.util.concurrent.Executors to nic więcej niż zbiór statycznych metod wygody, które budują wspólne aranżacje wykonawców.

Jeśli potrzebujesz czegoś konkretnego, co nie jest oferowane przez Executors, możesz swobodnie zbudować własną instancję klas implementacji, korzystając z przykładów w Executors jako przewodnika.

+3

IMHO ta odpowiedź jest mylące dla przedstawionego problemu, ponieważ sugeruje, że można po prostu skonstruować Executor że spełnia te szczególne wymagania. Ale czytanie dokumentacji [ScheduledThreadPoolExecutor] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html) wskazuje, że wywołanie kilku metod strojenia odziedziczonych po [ThreadPoolExecutor] (http : //docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html) "nie przynoszą żadnego użytecznego efektu" i dlatego pożądane zachowanie wydaje się nieobsługiwane przez 'ScheduledThreadPoolExecutor'. – rmoestl

-2

Jak mówi skaffman, Executors to tylko zbiór metod fabrycznych. jeśli potrzebujesz konkretnej instancji, zawsze możesz sprawdzić wszystkie istniejące implementatory Executor. W twoim przypadku myślę, że dzwonienie do jednego z różnych konstruktorów ScheduledThreadPoolExecutor byłoby dobrym pomysłem.

+0

Mimo to ScheduledThreadPoolExecutor ma ustawiony stały rozmiar. – nos

8

Zgodnie z projektem element ScheduledThreadPoolExecutor ma ustalony rozmiar. Można użyć wersji z pojedynczym wątkiem, która przesyła do zwykłej usługi ExecutorService w celu wykonania zadania. Ten wątek zdarzenia + puli pracowników jest dość łatwy do koordynowania, a elastyczność nadrabia dedykowany wątek. Używałem tego w przeszłości, aby zastąpić TimerTasks i inne niekrytyczne zadania, aby wykorzystać typowy executor jako ogólnosystemową pulę.

6

Sugerowana tutaj Why does ScheduledThreadPoolExecutor only accept a fixed number of threads? Obejście:

scheduledExecutor = new ScheduledThreadPoolExecutor(128); //no more than 128 threads 
scheduledExecutor.setKeepAliveTime(10, TimeUnit.SECONDS); 
scheduledExecutor.allowCoreThreadTimeOut(true); 
+4

** Uwaga przy użyciu tego rozwiązania **: rozważ to w [dokumentacji programu ScheduledThreadPoolExecutor] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html): _ "Ponadto prawie nigdy nie jest dobrym pomysłem ustawienie wartości corePoolSize na zero lub użycie ** allowCoreThreadTimeOut **, ponieważ może to opuścić pulę bez wątków do obsługi zadań, gdy tylko zaczną one działać." _ – rmoestl

+0

nie można uzyskać 'ScheduledThreadPoolExecutor' do wyświetlania tego zachowania. Przy domyślnej implementacji, jeśli pula wątków jest pusta, metoda 'ensurePrestart()', metoda prywatna wywoływana przez wszystkie metody planowania, utworzy pracownika do obsługi nowego zadania. Istota github: https://gist.github.com/Groostav/600edf739a39cbbb33cbd64ad385d621 – Groostav

+0

przeczytaj: oznacza to, że komentarz @rmoestl jest błędny, a strategia GKislina jest prawidłowa. Nadal oczywiście bardzo niepokoi fakt, że dokumenty sugerują, że nie jest to prawidłowa strategia i jest całkowicie możliwe, że czegoś brakuje. – Groostav

Powiązane problemy