Zakańczanie/wstrzymywanie pracy serwera wielowątkowego

Odpowiedz Nowy wątek
2018-12-29 15:36
0

Mam pytanie na które nie mogę znaleźć odpowiedzi.
Mam Selector który działa sobie w pętli while (true) na osobnym wątku (klasa implementuje Runnable). Uruchamiam wątek za pomocą ExecutorService. Chciałbym wstrzymać jego pracę/zabić instancję. Jak to zrobić?
Czy powinienem:

  • rzucić jakiś wyjątek, aby wywołać przerwanie (wydaje mi się to okropnym pomysłem)
  • korzystać z Observable
  • trzymać obiekt Future i na nim operować?

Każda pomoc i dyskusja mile widziane.


Pozostało 580 znaków

2018-12-29 18:40
1

Nie da się w Javie zatrzymać wątku. Możesz jedynie w tym Runnable zawołać Thread::interrupt czym zasugerujesz executor service, aby zatrzymał wątek, ale kiedy to nastąpi ciężko powiedzieć. Jeżeli aktualnie nie jesteś na jakiejś blokującej metodzie to powinno to stać się szybko. Jeżeli metoda blokująca jest dobrze napisana to rzuci InterruptedException i też skończy się w miarę szybko.

To jak responsywny w zamykaniu będzie Twój wątek zależy również od tego jakie metody tego Selectora używasz, select z timeoutem może Ci pomóć zwiększyć responsywność na sygnał zakończenia, ale kosztem CPU.


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


edytowany 2x, ostatnio: nie100sowny, 2018-12-29 18:46

Pozostało 580 znaków

2018-12-29 18:47
0

@nie100sowny: Czy w takim razie jest jakaś możliwość edytowania warunku pętli?
Nie mogę zatrzymać wątku, ale mogę zatrzymać pętlę - tylko pytanie teraz brzmi jak inteligentnie poinformować drugi wątek (czytaj wymienić informację między dwoma wątkami: sterującym i wykonawczym) tak, aby niepotrzebnie nie obciążać mojego wątku wykonawczego jakimś skomplikowanym sprawdzaniem, ale tak, żeby zauważył zmianę?
Jakieś teorie?


edytowany 1x, ostatnio: Burdzi0, 2018-12-29 18:48

Pozostało 580 znaków

2018-12-29 19:10
3

Warunek nie wiele pomoże. Po pierwsze musi to być zmienna volataile, aby mieć gwarancję odczytu, ale wciąż problem pozostaje ten sam:

  1. Warunek końca == true.
  2. Wołamy Selector::select i wątek się blokuje
  3. Ktoś ustawia warunek końca == false, ale nasz wątek wciąż jest zablokowany na select i tego nie widzi.

Ogólnie z tego co pamiętam dodanie Thread::isInterrupted do warunku while() to dobra praktyka.

Rozwiązania:

  1. Używać Selector::select z timeout np. 20 ms.
  2. Gdy chcesz zakończyć zawołać ExecutorService::shutdown / ExecutorService::awaitTermination musisz poczytać, bo concurrency to trudny temat, a ja ostatni raz w tym siedziałem z 2 lata temu :)
  3. Możesz też zamiast ExecutorService stworzyć wątek, wówczas z zewnątrz wołasz Thread::interrupt i Thread::join i wówczas możesz zaczekać na zakończenie wątku. Powinno działać o ile Runnable będzie respektował przerwania.

Porada:
Zajrzyj sobie do "Java Concurrency in Practice" Chapter 7: Cancellation and Shutdown


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


edytowany 5x, ostatnio: nie100sowny, 2018-12-29 19:18

Pozostało 580 znaków

2019-03-08 11:15
0

@nie100sowny: oczywiscie ze sie da zatrzymac. Ale sposob w jaki to mozna zrobic definitywnie nie nadaje sie na produkcje :)

Tak wiem. Thread::stop :) - nie100sowny 2019-03-08 11:30
Mi chodzilo o: Runtime.getRuntime().exec("kill -9 processPid") :) - WhiteLightning 2019-03-08 11:32

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0