2009-10-04 18 views
11

Mam obiekt MyThread, który uruchamiam, gdy moja aplikacja jest ładowana przez serwer, oznaczam ją jako wątek Daemona, a następnie wywołuję na nim kod start(). Wątek ma służyć do oczekiwania na informacje z kolejki, o ile aplikacja jest aktywna. Mój problem/pytanie brzmi następująco: Obecnie MyThread rozszerza wątek, ponieważ oznaczam go jako demona i czytam o tym, jak bardziej prawdopodobne jest wdrożenie Runnable i użycie Executorów. Tak więc chciałem zapytać, czy MyThread wdroży Runnable zamiast rozszerzenia Thread (i oczywiście zostanie zmieniona nazwa) i użyję newSingleThreadScheduledExecutor() jak, co lub gdzie, mogę oznaczyć coś jako Daemon. Mam nadzieję, że nie narobiłem bałaganu, proszę wybaczcie, jeśli mam, ponieważ niektóre elementy środowiska wielowątkowego są dla mnie bardzo nowe.Executor i demon w Javie

Dzięki Ittai

Aktualizacja: Moduł mam na myśli w mojej aplikacji jest aplikacja internetowa, która ma kilka wątków rzeczywiście tego rodzaju, a co oni mają wspólnego jest to, że oni w całej ServletContext jako członek z różnych powodów. Obecnie rozszerzam Thread na WebThread, który ma ServletContext jako memebr i wszystkie podklasy mogą z niego korzystać. Jeśli przejdę do paradygmatu Runnable z Executorem i ThreadFactory niż w zasadzie, potrzebuję mieć brzydką hybrydę WebRunnable, która implementuje Runnable i ma ServletContext jako członka publicznego i ma swój implementację newThread(WebRunnable arg0) oprócz newThread(Runnable arg0). Nie jestem pewien, co jest najlepsze. Dzięki

Odpowiedz

12

Jeśli używasz zaplanowanego executora, możesz podać ThreadFactory. Służy do tworzenia nowych wątków i można je modyfikować (np. Tworzyć demona) zgodnie z wymaganiami.

EDIT: Aby odpowiedzieć na aktualizację, na ThreadFactory prostu musi wdrożyć newThread(Runnable r) od twojej WebRunnablejestRunnable. Więc nie ma prawdziwej dodatkowej pracy.

+0

+1 za poprawność techniczną - ale czy jest jakaś korzyść z używania Executora w tym kontekście? Wydaje się dla mnie trochę "złożoności dla złożoności" (ale może się mylę w tym ...) – hjhill

+0

Być może nie. Ale napisałem systemy, przed których na początku używam jednego executora wątków, i podłączono różne executory na późniejszym etapie. –

+0

@ Brian - Myślę o tym, co myśli hjhill. Mam jeden wątek jako taki i nie jestem pewien, czy warto moich kłopotów z ponownym użyciem ThreadFactory – Ittai

23

Sprawdź JavaDoc dla newSingleThreadScheduledExecutor(ThreadFactory threadFactory)

byłoby realizowane mniej więcej tak:

public class MyClass { 
    private DaemonThreadFactory dtf = new DaemonThreadFactory(); 
    private ScheduledExecutorService executor = 
           Executors.newSingleThreadScheduledExecutor(dtf); 
    // ....class stuff..... 
    // ....Instance the runnable..... 
    // ....submit() to executor.... 
} 

class DaemonThreadFactory implements ThreadFactory { 
    public Thread newThread(Runnable r) { 
     Thread thread = new Thread(r); 
     thread.setDaemon(true); 
     return thread; 
    } 
} 
+0

Hi Stu, przede wszystkim dziękuję za szczegółową odpowiedź, ale nie jestem pewien, czy widziałem moją aktualizację? Uaktualniłem pytanie tym, że potrzebuję mojego 'Threads/Runnables' aby mieć obiekt' ServletContext' podczas wykonywania run i zastanawiam się, jak to może być acocmplished z Runnable. Wiem, że z dziedziczeniem 'Thread' nie ma problemu z podłączeniem go do' ThreadFactory', ale nie jestem pewien, czy i jak to jest możliwe z paradygmatem Runnable. – Ittai

+0

Ach, nie, nie zrobiłem: P * (otworzyłem twoje pytanie na odpowiedź, ale nie spieszyłem się z tym.) * Pozwól mi pomyśleć przez chwilę i sprawdź inną odpowiedź ... –

+0

Co zdecydowałem do zrobienia (może być zmienione) jest posiadanie klasy 'singleton', która ma' commonResourcesMap', która będzie '' i będzie służyć jako ten wspólny zasób dla serwletów i nie serwletów. W ten sposób mogę zaimplementować 'Runnable' bez problemu. – Ittai

2

Wystarczy uzupełnić z innego możliwego rozwiązania dla kompletności. To może nie być tak miłe.

final Executor executor = Executors.newSingleThreadExecutor(); 
Runtime.getRuntime().addShutdownHook(new Thread() { 

    @Override 
    public void run() { 
     executor.shutdownNow(); 
    } 
});