2012-02-10 13 views
7

Jestem w trakcie projektowania aplikacji opartej na języku graficznym Java, która uruchamia szereg oddzielnych zadań, każda w swojej własnej rozszerzonej klasie SwingWorker. Jest to normalny projekt, którego używam, aby uruchamiać zadania na własnych wątkach i nadal utrzymywać EDT za darmo, aby zaktualizować GUI. Każdy SwingWorker jest uruchamiany we własnym wątku za pomocą Executors.newCachedThreadPool.Java Swingworker i wiele wątków

Jednak w ramach jednej konkretnej klasy istnieje zadanie, które wymaga długiego czasu przetwarzania. Zadanie zawiera pętlę for wykonującą niektóre obliczenia do sześciu razy.

Mam pomysł na wdrożenie każdego z sześciu obliczeń w ich własnym wątku, aby przyspieszyć proces przetwarzania, ale nie jestem pewien najlepszego sposobu realizacji tego.

Czy można rozszerzyć SwingWorker i wdrożyć Runnable, a następnie użyć pustej metody Run() w pętli for, uruchamiając nowy wątek za każdym razem lub używając cachedThreadPool.

A może lepiej użyć standardowej implementacji wątku()?

Wszelkie porady lub sugestie będą mile widziane.

góry dzięki

Josh

+7

* "Miałem już pomysł wdrożenia każdego z sześciu obliczeń w ich własnym wątku, aby przyspieszyć proces przetwarzania" * [sic] ... Ten rodzaj obliczeń równoległych, aby przyspieszyć aplikację związaną z procesorem, może być tylko przyśpieszyć, jeśli procesor, na którym działa twoja aplikacja, ma co najmniej 6 rdzeni dostępnych dla twojej aplikacji Java. Jeśli masz tylko, powiedzmy, dwa rdzenie, to tarowanie 6 wątków zamiast dwóch powinno spowolnić twój program ... – TacticalCoder

+0

Ahh tak, to ma sens! Dziękuję. –

+0

@ user988052, który nie ma żadnego sensu. Jeśli masz x wątków, to niekoniecznie potrzebujesz co najmniej x rdzeni, aby program działał szybciej. Dopóki JVM ma więcej niż 1 logiczny procesor, system operacyjny spróbuje rozdzielić te wątki pomiędzy te logiczne procesory. Więcej logicznych procesorów - >> mniej wątków na procesor - >> kończy się szybciej. Może to być o wiele bardziej skomplikowane (na przykład w przypadku kilku blokad), ale zwykle działa w ten sposób. –

Odpowiedz

5

user988052 ma rację oczywiście - jeśli nie masz multi core CPU, wykonując obliczenia w sześciu różnych wątków faktycznie spowalniają swój wniosek z powodu narzutu która towarzyszy tworzeniu i administrowaniu wątkami.

Jeśli jednak chcesz wykonać te obliczenia w sześciu osobnych wątkach, możesz użyć SwingWorker jako wątku zarządzającego i odradzić 5-6 nowych wątków w nim. Korzystanie z ExecutorService byłoby wtedy drogą, ponieważ używa puli wątków, a tym samym minimalizuje narzut związany z tworzeniem i usuwaniem wątku.

Edycja: aby odpowiedzieć na komentarz:

Myślę, że najlepszym sposobem byłoby realizować swoje obliczenia w Runnable (tak, że każdy z sześciu obliczeń mogą działać oddzielnie), a następnie po prostu użyć ExecutorService instancję swoje Runnable sześć razy i użyj ExecutorService.submit(Runnable task). Możesz to zrobić w ramach metody SwingWorker.doInBackground().

Nie należy nigdy samodzielnie wywoływać metody run() - należy to zrobić za pomocą Thread/ExecutorService.

+0

Czy muszę więc utworzyć metodę run w klasie swingworker, a następnie wywołanie uruchomić za każdym razem, gdy chcę, aby nowy wątek był wykonywany przy użyciu executora? –

+0

Zobacz moją zmianę dotyczącą odpowiedzi na Twój komentarz. – mort

+0

Myślę, że to zależy w dużej mierze od tego, jak długo należy się spodziewać obliczeń. Jeśli mówimy o czasie obliczeń wynoszącym około 2 sekundy, to prawdopodobnie nie jest dobrym pomysłem korzystanie z 6 wątków. Ale jeśli jest to coś więcej niż 10 sekund, 30 sekund, 1 minuta, 5 minut itd., To 6 wątków ma sens. Całe obciążenie generowane przez tworzenie/administrowanie/przełączanie między 6 wątkami jest obecnie tanie w obliczeniach SOOOOOO, więc nie powinno to stanowić problemu. Jeśli uważasz, że tworzenie 6 wątków ma więcej sensu, zrób to. Może nawet przyspieszyć działanie, jeśli użytkownik ma dwurdzeniowy/potrójny rdzeń/czterordzeniowy rdzeń/etc. PROCESOR. –

Powiązane problemy