Jak zabić java.lang.Thread
w Javie?
java
multithreading
interrupt
Lecieć jak po sznurku
źródło
źródło
ExecutorStatus
tego pytania: stackoverflow.com/questions/2275443/how-to-timeout-a-threadOdpowiedzi:
Zobacz ten wątek firmy Sun, dlaczego są one przestarzałe
Thread.stop()
. Szczegółowo wyjaśnia, dlaczego była to zła metoda i co należy zrobić, aby bezpiecznie zatrzymać wątki w ogóle.Zalecają, aby używać zmiennej wspólnej jako flagi, która prosi wątek w tle o zatrzymanie. Ta zmienna może być następnie ustawiona przez inny obiekt żądający zakończenia wątku.
źródło
getConnection()
zjava.sql.DriverManager
. Jeśli próba połączenia trwa zbyt długo, próbuję zabić odpowiedni wątek, dzwoniąc,Thread.interrupt()
ale nie ma to żadnego wpływu na wątek.Thread.stop()
Działa jednak, choć Oracle twierdzi, że nie powinno działać, jeśliinterrupt()
nie robi. Zastanawiam się, jak to działa i unikaj stosowania przestarzałej metody.Generalnie nie ..
Poprosisz go, aby przerwał cokolwiek robi za pomocą Thread.interrupt () (link javadoc)
Dobre wyjaśnienie, dlaczego znajduje się w javadoc tutaj (link do java technote)
źródło
interrupt()
wywoływana jest metoda? Główne pytanie dotyczy generowania dziennika dla każdego nowego wątku.W Javie wątki nie są zabijane, ale zatrzymanie wątku odbywa się w trybie współpracy . Wątek jest proszony o zakończenie, a następnie można go bezpiecznie zamknąć.
Często
volatile boolean
używane jest pole, które wątek okresowo sprawdza i kończy, gdy zostanie ustawione na odpowiednią wartość.Nie użyłbym a,
boolean
aby sprawdzić, czy wątek powinien się zakończyć . Jeśli użyjesz govolatile
jako modyfikatora pola, będzie to działało niezawodnie, ale jeśli kod stanie się bardziej złożony, ponieważ zamiast tego używa innych metod blokowania wwhile
pętli, może się zdarzyć, że Twój kod w ogóle się nie zakończy lub przynajmniej zajmie więcej czasu, ponieważ może chcieć.Każdy wątek ma już status przerwania flagi logicznej i powinieneś z niego skorzystać. Można to zaimplementować w następujący sposób:
Kod źródłowy zaadaptowany z Java Concurrency in Practice . Ponieważ
cancel()
metoda jest publiczna, możesz pozwolić innemu wątkowi wywoływać tę metodę, jak chcesz.źródło
Jednym ze sposobów jest ustawienie zmiennej klasy i użycie jej jako wartownika.
Ustaw zmienną klasy zewnętrznej, tj. Flag = true w powyższym przykładzie. Ustaw wartość false, aby „zabić” wątek.
źródło
volatile
aby upewnić się, że działa poprawnie wszędzie. Klasa wewnętrzna nie jest statyczna, więc flaga powinna być zmienną instancji. Flaga powinna zostać wyczyszczona metodą akcesora, aby można było wykonać inne operacje (takie jak przerwanie). Nazwa „flaga” nie ma charakteru opisowego.Jest sposób, jak to zrobić. Ale jeśli musiałeś go użyć, albo jesteś złym programistą, albo używasz kodu napisanego przez złych programistów. Powinieneś więc pomyśleć o tym, aby przestać być złym programistą lub przestać używać tego złego kodu. To rozwiązanie dotyczy tylko sytuacji, gdy NIE MA INNEGO SPOSOBU.
źródło
Thread.stop
nawet jeśli jest przestarzała.Thread.stop
robi to samo, ale sprawdza także dostęp i uprawnienia. UżywanieThread.stop
jest raczej oczywiste i nie pamiętam powodu, dla którego go użyłemThread.stop0
. MożeThread.stop
nie działało w moim specjalnym przypadku (Weblogic na Javie 6). A może dlatego, żeThread.stop
jest przestarzały i powoduje ostrzeżenie.Chcę dodać kilka obserwacji na podstawie zebranych komentarzy.
Thread.stop()
zatrzyma wątek, jeśli menedżer bezpieczeństwa na to zezwoli.Thread.stop()
jest niebezpieczny. Powiedziawszy to, jeśli pracujesz w środowisku JEE i nie masz kontroli nad wywoływanym kodem, może być konieczne; zobacz Dlaczego Thread.stop jest przestarzałe?stop()
tworzy nowyThreadDeathError
błąd w wątku wywołującym, a następnie zgłasza ten błąd w wątku docelowym . Dlatego ślad stosu jest generalnie bezwartościowy.stop()
sprawdza u menedżera bezpieczeństwa, a następnie wywołujestop1()
te połączeniastop0()
.stop0()
jest rodzimym kodem.Thread.stop()
nie została jeszcze usunięta), aleThread.stop(Throwable)
została usunięta w wersji Java 11. ( lista mailingowa , JDK-8204243 )źródło
Głosowałbym na
Thread.stop()
.Na przykład masz długotrwałą operację (jak żądanie sieciowe). Podobno czekasz na odpowiedź, ale może to zająć trochę czasu, a użytkownik przejdzie do innego interfejsu użytkownika. Ten oczekujący wątek jest teraz a) bezużyteczny b) potencjalny problem, ponieważ kiedy uzyska wynik, jest całkowicie bezużyteczny i wywoła wywołania zwrotne, które mogą prowadzić do wielu błędów.
Wszystko to, a on może przetwarzać odpowiedzi, które mogą wymagać dużej mocy obliczeniowej. A Ty, jako programista, nie możesz nawet tego zatrzymać, ponieważ nie możesz rzucać
if (Thread.currentThread().isInterrupted())
wierszy w całym kodzie.Więc niemożność silnego zatrzymania nici jest dziwna.
źródło
Thread.stop()
bezpiecznie dzwonić . Nie głosujesz zaThread.stop()
, prosisz o każdą osobę, która realizuje każdą operację, która może zająć dużo czasu, aby bezpiecznie ją przerwać. I może to być dobry pomysł, ale nie ma to nic wspólnego z wdrażaniemThread.stop()
jako sposobu żądania bezpiecznej aborcji. Już to mamyinterrupt
.stop
.Pytanie jest raczej niejasne. Jeśli miałeś na myśli „jak napisać program, aby wątek przestał działać, kiedy tego chcę”, wówczas różne inne odpowiedzi powinny być pomocne. Ale jeśli miałeś na myśli „Mam awarię z serwerem, nie mogę teraz zrestartować się i potrzebuję tylko konkretnego wątku, aby umrzeć, chodź co może”, to potrzebujesz narzędzia interwencyjnego, aby dopasować takie narzędzia monitorowania
jstack
.W tym celu stworzyłem jkillthread . Zobacz instrukcję użytkowania.
źródło
Oczywiście zdarza się, że uruchamiasz jakiś niezupełnie zaufany kod. (Mam to osobiście, umożliwiając wykonywanie przesłanych skryptów w moim środowisku Java. Tak, wszędzie dzwoni alarm bezpieczeństwa, ale jest to część aplikacji.) W tym niefortunnym przypadku po prostu masz nadzieję, pytając pisarzy skryptów szanować jakiś rodzaj logicznego sygnału uruchomienia / nie uruchomienia. Jedynym przyzwoitym zabezpieczeniem przed awarią jest wywołanie metody stop w wątku, jeśli, powiedzmy, działa on dłużej niż pewien limit czasu.
Ale jest to po prostu „przyzwoite”, a nie bezwzględne, ponieważ kod może wychwycić błąd ThreadDeath (lub jakikolwiek wyjątek, który jawnie zgłaszasz) i nie wyrzucać go tak, jak powinien to zrobić dżentelmen. Tak więc, podstawową kwestią jest AFAIA, nie ma absolutnie bezpiecznej awarii.
źródło
Nie ma sposobu, aby z wdziękiem zabić wątek.
Możesz spróbować przerwać wątek, jedną wspólną strategią jest użycie trującej pigułki, aby wysłać wiadomość do wątku, aby się zatrzymał
}
http://anandsekar.github.io/cancel-support-for-threads/
źródło
Zasadniczo nie zabijasz, nie zatrzymujesz ani nie przerywasz wątku (ani nie sprawdzasz, czy jest przerwany ()), ale pozwalasz mu zakończyć się naturalnie.
To jest proste. Możesz użyć dowolnej pętli razem z (lotną) zmienną logiczną wewnątrz metody run () do kontrolowania aktywności wątku. Możesz także powrócić z aktywnego wątku do głównego wątku, aby go zatrzymać.
W ten sposób z wdziękiem zabijasz wątek :).
źródło
Próby nagłego zakończenia wątku są dobrze znaną złą praktyką programistyczną i dowodem złego projektowania aplikacji. Wszystkie wątki w aplikacji wielowątkowej jawnie i niejawnie współużytkują ten sam stan procesu i są zmuszone do współpracy ze sobą, aby zachować spójność, w przeciwnym razie twoja aplikacja będzie podatna na błędy, które będą naprawdę trudne do zdiagnozowania. Dlatego obowiązkiem programisty jest zapewnienie takiej spójności poprzez staranne i przejrzyste projektowanie aplikacji.
Istnieją dwa główne właściwe rozwiązania kontrolowanych zakończeń wątków:
Dobre i szczegółowe wyjaśnienie problemów związanych z nagłym zakończeniem wątków, a także przykłady niewłaściwych i właściwych rozwiązań kontrolowanego zakończenia wątków można znaleźć tutaj:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
źródło
Oto kilka dobrych lektur na ten temat:
Co robisz z InterruptedException?
Czyste zamykanie wątków
źródło
Nie udało mi się przerwać pracy w Androidzie, więc użyłem tej metody, działa idealnie:
źródło
„Zabicie wątku” nie jest właściwym zwrotem. Oto jeden ze sposobów, w jaki możemy zaimplementować płynne zakończenie / wyjście z wątku:
Runnable, którego użyłem:
Klasa wyzwalająca:
źródło
Thread.stop jest przestarzałe, więc jak zatrzymać wątek w Javie?
Zawsze używaj metody przerwania i w przyszłości, aby poprosić o anulowanie
źródło