W kontekście Java, tworzę nowy wątek do odczytu wejścia sieciowego po otwarciu okna GUI, a kiedy zamknę okno, chcę zwolnić zasób gniazda i natychmiast zakończyć wątek. Teraz używam metody setSoTimeout, ale nie chcę czekać wyjątek timeout. Czy ktokolwiek mógłby dać jakąś sugestię? Dzięki!Jak natychmiast zakończyć blokowanie wątków w operacji gniazda IO?
Odpowiedz
Są to (potencjalnie) trzy sposoby, aby to zrobić:
Wywołanie
Socket.close()
na gnieździe zamknie związaneInputStream
iOutputStream
przedmiotów i powodować żadnych wątków zablokowanych w gniazda lub operacji (związany) strumień być odblokowanym. Zgodnie z javadoc operacje na samym gnieździe wyrzucąSocketException
.Wywołanie spowoduje (w pewnych okolicznościach, które nie są określone) przerwać operację blokowania I/O, powodując, że rzuca ona
InterruptedIOException
.Uwaga na zastrzeżenie. Najwyraźniej metoda "interrupt()" nie działa na "większości" nowoczesnych platform Java. (Jeśli ktoś miałby czas i skłonność, mógłby zbadać okoliczności, w których to podejście działa, ale sam fakt, że zachowanie jest specyficzne dla danej platformy, powinien wystarczyć, aby powiedzieć, że powinieneś go używać tylko wtedy, gdy potrzebujesz tylko swojej aplikacji do pracy na określonym platformy. w tym momencie można łatwo „wypróbować” dla siebie.)
Ewentualny trzeci sposób to zrobić, to zadzwonić
Socket.shutdownInput()
i/lubSocket.shutdownOutput()
. Javadocs nie mówią jednoznacznie, co dzieje się z operacjami odczytu i/lub zapisu, które są obecnie zablokowane, ale nie jest nierozsądne myślenie, że odblokują one i wyrzucą wyjątek. Jeśli jednak javadoc nie powie, co się stanie, należy przyjąć, że zachowanie jest specyficzne dla danej platformy.
Proszę, w jakich okolicznościach threadinterterrupt() przerwie blokowanie operacji we/wy? –
Xu DXn - nie jest to udokumentowane. Niektóre strumienie realizują to, inne nie. Aby poznać szczegóły, przeczytaj kod źródłowy OpenJDK. Chodzi mi o to, że może działać, ale nie musi. –
całkiem pewnie większość implementacji jvm nie _pomaga obsługiwać operacji przerywalnych io. Myślę, że być może sun solaris jvm wspierał go w pewnym momencie. – jtahlborn
Wiem, że to pytanie jest stary, ale jak nikt nie wydaje się być rozwiązany „tajemnicę” Thread.interrupt()
na „nowoczesnych platform” Zrobiłem rozeznanie.
Zostało to przetestowane na Javie 8 na Windows7 (64-bit) (ale może się to również sprawdzić na innych platformach).
Wywołanie Thread.interrupt()
robi nie rzucać InterruptedIOException
Co się dzieje, jest to, że metoda InputStream.read()
powraca z -1
i Thread.interrupted()
FLAG jest ustawiony.
Więc dodaje można uznać za 'poprawione' read() rzuca InterruptedIOException
:
static final int read(Socket socket, byte[] inData)
throws SocketTimeoutException, // if setSoTimeout() was set and read timed out
InterruptedIOException, // if thread interrupted
IOException // other erors
{
InputStream in = socket.getInputStream();
int readBytes = in.read(inData, 0, inData.length);
if (Thread.interrupted())
{
throw new InterruptedIOException("Thread interrupted during socket read");
}
return readBytes;
}
Ta odpowiedź zasługuje na więcej głosów, ponieważ zachowanie Java podczas przerw w działaniu strumienia wejścia/wyjścia nie jest tym, czego wielu ludzi się spodziewa. –
- 1. aktorzy scala vs wątki i blokowanie IO
- 2. Blokowanie wątków Java
- 3. AVPlayer „Nie można zakończyć operacji”
- 4. .NET wątki wątków i asynchroniczne wątki IO
- 5. Pętla zdarzeń vs blokowanie wielowątkowe IO
- 6. Jak wykonać blokowanie IO w pracy z iskrami Apache?
- 7. laravel echo z REDiS i gniazda IO
- 8. Blokowanie blokad a Blokowanie niezablokowujące
- 9. Integracja węzła js i gniazda IO z podpisem kodu
- 10. Jak ustawić limit czasu na blokowanie gniazd w asiu?
- 11. Blokowanie bez blokowania
- 12. połączenie użytkownika gniazda io dodane na każdym odświeżeniu strony html?
- 13. strumień nie obsługuje jednoczesne IO odczytu lub zapisu operacji
- 14. Po wstrzymaniu na oświadczeniu w narzędziach przeglądarki przeglądarki, jak zakończyć wykonywanie natychmiast po tym oświadczeniu?
- 15. Zarządzanie pulami wątków agenta w Clojure
- 16. Jak zapobiegać głodom wątków w C++ 11
- 17. Jak zakończyć proces w vbscript
- 18. Jak w niezawodny sposób oczyszczać wątki Rusta blokujące IO?
- 19. Użyj wielo-przetwarzania/wątków do przerwania operacji numpy na kawałki
- 20. Zablokowanie gniazda zwraca EAGAIN
- 21. Blokowanie istnienia pliku w Javie
- 22. Tworzenie DOM, który jest bezpieczny dla wątków dla operacji odczytu
- 23. Jak mogę zakończyć QThread
- 24. NSPredicate: jak NIE ZAKOŃCZYĆ?
- 25. Jak zakończyć scalanie pliku?
- 26. Jak zakończyć tryb "debugowania"?
- 27. Co się stanie, jeśli nie ma wątków IO do obsługi wyniku asynchronicznego?
- 28. Jak zakończyć aplikację Xamarin?
- 29. Zapewnianie zamykania plików natychmiast
- 30. Jak wymusić wypowiedzenie wszystkich pracowników w ThreadPoolExecutor natychmiast
ja nie rozumiem, dlaczego to ma -1?!? Myślę, że pytanie było dość jasne i na miejscu. –