2012-12-18 12 views
7

Zaimplementowałem subskrypcję w mojej aplikacji Java. Kiedy nowy abonent dodał, aplikacja tworzy nowe zadanie (klasa, która implementuje Runnable być uruchamiane w osobnym wątku) i jest dodawana do ExecutorService jak:Zatrzymaj Runnable przesłane do ExecutorService

public void Subscribe() 
{ 
    es_.execute(new Subscriber(this, queueName, handler)); 
} 

//... 

private ExecutorService es_; 

Aplikacja może zarejestrować dowolną liczbę abonentów, jak chcesz. Teraz chcę zaimplementować coś w rodzaju Unsubscribe, aby każdy subskrybent miał możliwość zatrzymania przepływu komunikatów. Tutaj potrzebuję sposobu, aby zatrzymać jedno z zadań działających w ExecutorService. Ale nie wiem, jak to zrobić.

Thei jego odmiany nie są dla mnie: kończą wszystkie zadania, chcę tylko zakończyć jedno z nich. Szukam rozwiązania. Tak proste, jak to możliwe. Dzięki.

Odpowiedz

8

Można użyć ExecutorService#submit zamiast execute i używać wracającą Future obiektu, aby spróbować i anulować zadanie za pomocą Future#cancel

Przykład (Zakładając Subscriber jest Runnable):

Future<?> future = es_.submit(new Subscriber(this, queueName, handler)); 
... 
future.cancel(true); // true to interrupt if running 

Ważna uwaga z komentarzy:

If your task doesn't honour interrupts and it has already started, it will run to completion.

+0

byłoby pomocne, jeśli edytujesz swoją odpowiedź, aby dodać prosty przykład. Mogę znaleźć wszystkie rzeczy w dokumentacji i google, ale odpowiedzi nie są dla mnie tylko dla innych. To może zaoszczędzić trochę (nieoceniony) czas. – maverik

+0

Oto, prosty przykład: –

+0

Dzięki. To jest naprawdę pomocne. – maverik

3

Zamiast używać ExecutorService.execute(Runnable) spróbuj użyć Future<?> submit(Runnable). Ta metoda prześle do puli Runnable w celu wykonania i zwróci obiekt o wartości Future. W ten sposób będziesz mieć odniesienia do wszystkich wątków subskrybentów.

Aby zatrzymać konkretny wątek, wystarczy użyć futureObj.cancel(true). Spowoduje to przerwanie bieżącego wątku, wyrzucenie InterruptedException. Wątek subskrybenta powinien być zakodowany w taki sposób, aby przerwał przetwarzanie w przypadku tego wyjątku (na przykład Thread.sleep(millis) z blokiem próbnym/catch dla całej metody).

można cand znaleźć więcej informacji na oficjalnej API: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

Powiązane problemy