2012-03-21 23 views
7

Mam aplikację, w której, gdy statystyki "gry", zaczyna się kilka różnych wątków. Zacznę wątki tak:Dobra praktyka do wielowątkowości

Thread thread = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     //... 
    } 
}); 

thread.setName("killMeAtEnd"); 
thread.start(); 

Później, gdy gra się kończy Mam metodę Dispose() wewnątrz gry, który sortuje przez wszystkich uruchomionych wątków i kończy wszystkie wątki, które mają nazwę „killMeAtEnd” . Moje pytanie brzmi: czy to dobra praktyka? Moją intencją jest, aby moja aplikacja działała szybko i bez bałaganu, z mojego doświadczenia Wątki, które pozostały "wiszące", spowalniają telefon do czasu zakończenia aplikacji. Czy jest lepszy sposób to zrobić? Czy to nawet warte zastanowienia?

EDIT:

Oto moja dispose() jeśli ktoś był zainteresowany. Ten kod znajduje się w grze klasowej.

public void dispose() 
{ 
    Thread threads[] = (Thread[])Thread.getAllStackTraces().keySet().toArray(); 
    for(int x=0;x<threads.length;x++) 
    { 
     Thread thread = threads[x]; 
     if(thread.getName().equalsIgnoreCase(KILL)) 
     { 
      try 
      { 
       thread.interrupt(); 
      }catch(Exception e){Log.e(Viewer.GAME,Log.getStackTraceString(e));} 
      thread = null; 
     } 
    } 
} 

public static final String KILL = "endOnDispose"; 
+0

Uzyskiwanie stacktraces jest dość kosztowne, więc byłoby wydajniejsze, gdybyś zapisał 'thread []' podczas tworzenia wątków i uczynił je 'dispose (Thread [] threads)'. Czy istnieją inne wątki, które wciąż działają, gdy gra się kończy, czy też ma to zapobiec zabiciu wątku interfejsu użytkownika? – zapl

+0

Po zakończeniu "gry" działanie nie kończy się, przechodzi do czegoś innego. – John

Odpowiedz

4

Masz prawo pomysł, ale istnieją pewne obszary do poprawy:

  1. Zamiast zapytań system dla wszystkich uruchomionych wątków, wystarczy dodać do listy wątków w dowolnym momencie ich tworzenia. Następnie możesz przerwać wszystkie utworzone wątki lub poczekać na ich zakończenie (dołączenie).
  2. Przerwanie przerywa tylko wątek w stanie blokowania, więc musisz mieć dodatkową flagę, którą wątek sprawdza okresowo (tj. Po każdym "cyklu pracy").
  3. Złap wyjątek przerwania wewnątrz wątku i obsłuż go (tzn. Wyjdź z wdziękiem).
+0

+1 Dzięki! Skończyło się na tym, że wszystkie moje wątki znalazłem na liście, a następnie zabiłem je po zakończeniu gry. – John

3

To nie jest koniecznie złym rozwiązaniem, ale istnieje kilka problemów:

  • Jeśli wątki są wątków roboczych w tym rodzaju, które zajmują jedno zadanie do wykonania, nie ma prawdopodobnie lepszy projekt, w którym wątek się kończy. Innymi słowy, istnieje prawdopodobnie lepszy przepływ wykonania, który nie wymaga zabicia na końcu.

  • Kiedy mówisz "sortuj przez wszystkie działające wątki ...", wyobrażam sobie, że patrzysz na WSZYSTKIE działające wątki w JVM? jak w czymś podobnym do linii this SO question? Jeśli tak jest, dlaczego nie chcesz po prostu zachować odniesienia do wszystkich wątków, które posiada Twoja gra, a następnie zabijać je? W przeciwieństwie do szukania tylko "killMeAtEnd"; Nie mogę myśleć o tym, jak twoja strategia może pójść źle, ale wydaje się nieco bardziej przejrzyste śledzenie twoich wątków.

Zdecydowanie dobrą praktyką jest utrzymywanie wątków w czystości. Jeśli twoje wątki robią coś mniej konkretnego-zorientowanego na zadania (np. Czekając na sieć io coś), to moja pierwsza sugestia jest nieco nieistotna. Sugerowałbym bycie bardzo ostrożnym przy projektowaniu, w jaki sposób utrzymujesz swoje nici w czystości, ponieważ błędy w wątkach mogą być wielkim bólem.

+0

+1 dzięki za pomoc! – John

0

Klasa ExecutorService już istnieje, aby poradzić sobie z tego rodzaju problemem.

Wykonaj wszystkie zadania wątków dla ExecutorService.

Po zakończeniu gry zamknij ExecutorService za pomocą shutdownNow. Spowoduje to przerwanie przerwania wszystkich wątków w ExecutorService.Następnie możesz utworzyć nową usługę ExecutorService po rozpoczęciu nowej gry.

Jeśli liczba wątków jest stała, można użyć Executors.newFixedThreadPool(), aby utworzyć ExecutorService.

Jeśli liczba wątków jest zmienna, można użyć Executors.newCachedThreadPool do utworzenia ExecutorService.

Powiązane problemy