2010-02-16 17 views
11

Odwołując się do pakietu java.util.concurrent i interfejsu Future zauważam (chyba że się mylę), że zdolność do uruchamiania długich zadań i możliwość zapytania na Postęp przychodzi tylko z klasą implementacji SwingWorker.Możliwość uzyskania postępu w Przyszłości <T> obiekt

Nasuwa się następujące pytanie:

Czy istnieje sposób, w non-GUI aplikacji non-Swing (obrazowanie aplikacji konsoli), aby rozpocząć czasochłonne zadanie w tle i pozwalają na inne wątki do wglądu postęp ? Wydaje mi się, że nie ma powodu, dla którego ta zdolność powinna być ograniczona do aplikacji typu swing/GUI. W przeciwnym razie jedyną dostępną opcją, tak jak ją widzę, jest przejście przez ExecutorService :: submit, która zwraca obiekt Future. Jednak bazowy interfejs Future nie pozwala na monitorowanie postępu.

+2

Zobacz http://stackoverflow.com/questions/2003354/how-can-i-report-progress-from-a-background-task – Mark

Odpowiedz

5

Oczywiście Future obiekt byłby dobry do blokowania, a następnie odbiera tylko wynik.

Przesłany obiekt, który można przesłać, musi albo wiedzieć, jak podać ten postęp (procent ukończenia, liczbę prób, status (wyliczać?) Itd.) I podać jako wywołanie API do samego obiektu, lub opublikowane w jakimś źródle wyszukiwania (w razie potrzeby w mapach pamięci lub bazie danych). Dla uproszczenia I mają tendencję do samego obiektu, zwłaszcza, że ​​masz zamiar najprawdopodobniej potrzebny jest uchwyt (ID) do wyszukiwania obiekt lub odniesienie do samego obiektu.

To znaczy, że masz 3 wątki robocze. 1 dla rzeczywistej pracy, 1, która jest blokowana podczas oczekiwania na wynik, i 1, która jest wątkiem monitorującym. Ten ostatni może być udostępniany w zależności od Twoich wymagań.

1

Miałem nadzieję, że nie było standardowe ramy współbieżności sposób być na bieżąco o postępach w długim zadania bez konieczności biegania program kliencki się martwić o wzniecanie i synchronizacji wszystko poprawnie. Wydawało mi się, że można wyobrazić sobie rozszerzoną wersję interfejsu Future<T>, która obsługuje: public short progress(); oprócz zwykłych metod isDone() i get(). Oczywiście realizacja progress() musiałaby następnie sondować obiektu bezpośrednio, więc może Future<T> musiałaby być określona jako Future<T extends CanReportProgress> gdzie CanReportProgress jest następujący interfejs:

public interface CanReportProgress { 
    public short progress(); 
} 

Nasuwa się pytanie, dlaczego ktoś przeszkadza, aby przejść przez obiekt Future w przeciwieństwie do wywoływania samego obiektu, aby uzyskać postęp. Nie wiem Będę musiał poświęcić mu więcej uwagi. Można argumentować, że jest bliżej do bieżącej umowy/semantyki której przedmiotem Callable nie jest sama, obejrzano ponownie przez programistę klienta po wywołaniu ExecutorService::submit/execute.

+0

Nic nie wiem o pudełku JDK, które mogłoby ci pomóc o wiele więcej niż zabranie SwingWorker (część 1.6 JDK) jako przykładu tego, jak może wyglądać wersja inna niż Swing. Używa RunnableFuture i getProgress() (z powiadomieniem o zdarzeniu)).Brzmi to dla mnie solidnym początkiem, ponieważ jest to znana ilość i od lat jest rozwijana/testowana przez większe umysły. Powodzenia. – Matt

+3

Należy zauważyć, że T w przyszłości oznacza klasę zwracanej wartości. Nie możesz uzyskać dostępu do T, dopóki zadanie się nie zakończy. Więc nie ma znaczenia, czy T wydłuży CanReportProgress. – Anderson

1

W moim przypadku przekazałem HashSet, z obiektami do przetworzenia, jako parametr metody, która została utworzona jako zmienna instancji w klasie wywołującej. Kiedy metoda asynchroniczna usuwa Obiekty po przetworzeniu, można pobrać rozmiar mapy pozostającej w metodzie wywołującej. Ogólnie rzecz biorąc, przechodzenie przez Obiekty poprzez Odniesienie rozwiązuje Problem.