Concurrency i reactive programming

0

Hej. Czytam sobie ostatnio książkę "Modern java in Action" - https://www.manning.com/books/modern-java-in-action.

Doszedłem do części V o ulepszeniach w java concurrency - te wszystkie CompletableFuture i reactive programming.

Takie pytanie do Was, bardziej doświadczonych - czy tego się używa w praktyce w normalnej pracy ? Jeśli tak to moglibyście podać jakieś przykłady ? Szczerze mówiąc trochę coś tam poczytałem, ale koniec końców przeszedłem do kolejnej części, bo w obecnej pracy (bankowość) nie mam chyba totalnie gdzie tego zastosować i nikt tego nie używa, a nie lubię się uczyć czegoś z czego nie korzystam bo zapomnę (cała reszta książki jak najbardziej przyswojona i na plus). W moich obecnych projektach również jeszcze nie miałem sposobności na użycie. Widziałem, że są jakieś jugi i confitury o tym, ale czy to nie jest bardziej sztuka dla sztuki ? Podobnie nigdy nie ruszyłem tak na serio wielowątkowości na tym niskim poziomie .. nie wiem czy to strasznie wielki grzech ? :O

Bo ogólnie to staram się ciągle czegoś nowego uczyć albo wracać do podstaw, ale w coraz większych szczegółach i nie wiem czy nie sensowniej byłoby ogarniać coś bardziej przydatnego.

No chyba, że pojawia się to gdzieś na rozmowach, ale póki co nie wiedziałem w ogłoszeniach takich wymagań. Podobnie jak javy 9.

Pozdrawiam serdecznie.

1

Ogólnie masz rację - rzadko kiedy javowiec tyka się wielowątkowości. Owszem są przypadki że coś trzeba tak zrobić, ale to zależy od branży. U mnie np do tej pory to albo dodawanie przy niektórych metodach synchronized albo ustawienie liczby wątków dla thread connection poola :P

EDIT: sorry, przypomniało mi się że gdzieś tam były jednak ExecutorServicy - chyba przy generowaniu raportów pdf czy coś, już nie pamiętam dokładnie

1

Jak się używa klasycznego springa lub javaee to nawet nie bardzo się da tykać wątków bezpiecznie:(
Poza tym normalne, ale raczej używam faktycznie prog współbieżnego w Scali.
CompletableFuture i mnóstwo klas z java.util to niskopoziomowce. Niebezpieczne w użyciu.
Warto sobie przyswoić executorsservice, aktorów i (dla hardkorów STM). Jest książka Venkata na ten temat.

Jak frameworki-kupy zajmą swoje miejsce na śmietniku historii to ta wiedza będzie przydatna.
Ogólnie im więcej rdzeni w procku tym bardziej wszystko oparte o synchronized, locki i transakcje marnuje zasoby.

2

Ogólnie masz rację - rzadko kiedy javowiec tyka się wielowątkowości.

smutek na mej twarzy wywołujesz mości panie.

U mnie np do tej pory to albo dodawanie przy niektórych metodach synchronized

Mam nadzieje że to nie wygląda tak :

/**
 * This is Thread safe - I know that - I am certified java developer !
 */
class C<T> {

    T val;

    public synchronized void setVal(T val)
    {
        if(val == null)
        {
            this.val = val;
        }
    }

    public T getVal()
    {
        return val;
    }
}

Jeśli tak to moglibyście podać jakieś przykłady

ale przykłady czego ? "reaktywnego" programowania ? "reaktywne programowanie" to bulszit, buzzword, kolejny z wielu. Ogarnij na czym polega nieblokowanie, potem zrozumiesz wszystko inne. Zacznij od podstaw, znalazłem ostatnio fajny blog-post na ten temat :

http://www.kodujze.pl/java-nio-prosty-nieblokujacy-serwer/

w dobie ogólnoświatowej sraczki na "reaktywne" programowanie - której jest niczym innym jak http://www.kegel.com/c10k.html w mejnstrimie, ludzie zapominają skąd i po co ... dokąd zmierzamy ?

1
rubaszny_karp napisał(a):

Ogólnie masz rację - rzadko kiedy javowiec tyka się wielowątkowości.

smutek na mej twarzy wywołujesz mości panie.

Z tym, że taka jest prawda. Znajdą się ciekawe projekty w których wykorzystanie wielowątkowości jest pożądane, a wręcz wymagane, jednakże jest ich mniej niż typowych CRUD'ów pisanych w JavaEE/Springu. Dodanie w takim stacku dodatkowych wątków jest jak samobójstwo, zresztą @jarekr000000 już o tym powiedział.

Jeśli tak to moglibyście podać jakieś przykłady

ale przykłady czego ? "reaktywnego" programowania ? "reaktywne programowanie" to bulszit, buzzword, kolejny z wielu. Ogarnij na czym polega nieblokowanie, potem zrozumiesz wszystko inne. Zacznij od podstaw, znalazłem ostatnio fajny blog-post na ten temat :

http://www.kodujze.pl/java-nio-prosty-nieblokujacy-serwer/

w dobie ogólnoświatowej sraczki na "reaktywne" programowanie - której jest niczym innym jak http://www.kegel.com/c10k.html w mejnstrimie, ludzie zapominają skąd i po co ... dokąd zmierzamy ?

Sprowadzanie terminu reaktywnego programowania do nieblokowania jest dość nietrafione. Ot, nieblokujący serwer może spełnić jedno (Responsive) z czterech podstawowych założeń systemów reaktywnych. Warto się troszkę głębiej zastanowić nad sensem całego reactive manifesto (https://www.reactivemanifesto.org/) niż tylko mówić herp derp - nieblokowanie. Nie mniej zgadzam się, że samo stwierdzenie "reaktywne programowanie" staje się kolejnym buzzwordem ale to nic dziwnego, co roku jakiś jest.

W Javie, w większości projektów nie spotkasz reaktywnego programowania ze względu na ograniczenia samego języka, a dokładniej jego rozwlekłą składnie (oraz niechęć do niemutowalności i inne dziwne problemy). Inne języki są w tej kwestii bardziej rozwinięte, a jak wiadomo narzędzia powinno się dobierać do problemów. Jeśli coś nie ma sensu w Javie, to warto rozważyć inne języki, np. Scale lub Kotlin'a (z JVM).

0
jarekr000000 napisał(a):

Jak się używa klasycznego springa lub javaee to nawet nie bardzo się da tykać wątków bezpiecznie:(

Możesz rozwinąć? Czego należy unikać? Używanie np. ExecutorService w springu jest złe?

0
DisQ napisał(a):

Z tym, że taka jest prawda. Znajdą się ciekawe projekty w których wykorzystanie wielowątkowości jest pożądane, a wręcz wymagane, jednakże jest ich mniej niż typowych CRUD'ów pisanych w JavaEE/Springu.

Apki webowe klasy enterprise w Springi nie muszą być gołymi CRUDami, żeby nie musieć kombinować w wątkach ;)

0
nut napisał(a):
jarekr000000 napisał(a):

Jak się używa klasycznego springa lub javaee to nawet nie bardzo się da tykać wątków bezpiecznie:(

Możesz rozwinąć? Czego należy unikać? Używanie np. ExecutorService w springu jest złe?

Generalnie chodzi o to, że jak wychodzisz po za ramy klasycznego Request per thread - i wątek na czas trwania żądania, to musisz pamiętać o zasadach JMM - a to, jest naprawdę wielki problem.

Kiedy chcesz wymieniać zmienne między wątkami, to musisz wiedzieć o tym, jak to zrobić poprawnie( initialization safety - mówi to panu coś ? ) - jeżeli to wiesz, śmiało, nie ma problemu.

0

@rubaszny_karp: chodzi tez o to że Szpring używa ThreadLocali do zarzadzania transakcjami, jak zaczniesz kombinowac executorService i @Transactional to może być problem :D
Ale bez @Transactional to ExecutorService czasami może być wykorzystywany :)

0
scibi92 napisał(a):

@rubaszny_karp: chodzi tez o to że Szpring używa ThreadLocali do zarzadzania transakcjami, jak zaczniesz kombinowac executorService i @Transactional to może być problem :D
Ale bez @Transactional to ExecutorService może być śmiało wykorzystywany :)

Spring to generalnie używa ThreadLocal to wszystkiego co można tam wsadzić - ale nie umiem se wyobrazić żeby to był jakiś problem.

0

Dzięki Wam :)

A jeśli np mamy jakąś metodę wystawioną przez resta, która ma coś zapisać w bazie i dodatkowo wygenerować na serwerze jakiś plik. Nie chcemy chyba tego generowania pliku robić synchronicznie tylko puścić w osobnym wątku i od razu zwrócić klientowi info, że zapisanie w bazie się powiodło, a info o tym, że plik wygenerowano ewentualnie pocisnać firebasem.

Widziałem coś takiego w springu jak @Async, ale chyba tu ktoś kiedyś to hejtował.

0

@Async będzie dobre. A hejtował pewno Jarek :D

1
Bambo napisał(a):

Dzięki Wam :)

A jeśli np mamy jakąś metodę wystawioną przez resta, która ma coś zapisać w bazie i dodatkowo wygenerować na serwerze jakiś plik. Nie chcemy chyba tego generowania pliku robić synchronicznie tylko puścić w osobnym wątku i od razu zwrócić klientowi info, że zapisanie w bazie się powiodło, a info o tym, że plik wygenerowano ewentualnie pocisnać firebasem.

Widziałem coś takiego w springu jak @Async, ale chyba tu ktoś kiedyś to hejtował.

To prawda, tylko musisz poczekać aż taki zapis się zakończy żeby móc o tym poinformować klienta, a to wymaga synchronizacji danych między wątkami, chyba że będziesz inaczej komunikować to klientowi, np gołębiem czy mailem

1

Nie siedzę w czystej Javie ale używam jej jeszcze podczas pracy (Android dev here) a tutaj wielowątkowość używana jest bardzo często, może to ci w czymś pomoże:

Na androidzie masz coś takiego jak wątek główny (UI) odpowiadający za to co jest wyświetlane na ekranie. W momencie gdy robisz jakiś request o dane z neta, gdybyś zrobił go na wątku UI to do momentu zakończenia requestu miałbyś zablokowany ten wątek, wyskoczył by ci ANR (Application not responding) co mogłoby spowodować ubicie aplikacji i zły user expierence. Do tego wykorzystujesz wątków pobocznych, na których wykonywana jest ta praca by wątek UI nie był blokowany. W momencie otrzymania odpowiedzi z neta i ew. przetworzenia informacji przesyłasz przemielone dane z wątku głównego do wątku UI a ten już odpowiada za wyświetlenie ich dla usera. To tak w uproszczeniu :)

0

@hcubyc:
Tak jak wspomniałem. Kiedy wygeneruje się raport idzie push do firebasa :) Client dzięki temu informuje usera o gotowości do pobrania pliku np.

A co do samego puszczania generowania pliku w innym wątku to ok .. nie stosować @Async. Czyli najlepiej jak puszczę to jako jakiś task w ExecutorService ?

0
Bambo napisał(a):

A co do samego puszczania generowania pliku w innym wątku to ok .. nie stosować @Async. Czyli najlepiej jak puszczę to jako jakiś task w ExecutorService ?

Jak masx jakiegoś springa to raczej zapomnij o javowym ExecutorService. Używa się wtedy Springowego TaskExecutora. Albo ,@Async.

0

Korzystając ze springa możesz też zastosowac rxjave/reactora/whatever. Dostajesz request, obsługujesz żądanie rxjava, która śmiga na jakiejś puli wątków i dalej łączysz sobie wywołania. Możesz robić np. tak, że stosujesz jedną pule watków na zależność (np baza danych, zewnętrzny serwis etc), springowe kontrolery od wersji 4 obsługują completable future.

0

Widziałem, że są jakieś jugi i confitury o tym, ale czy to nie jest bardziej sztuka dla sztuki ? Podobnie nigdy nie ruszyłem tak na serio wielowątkowości na tym niskim poziomie .. nie wiem czy to strasznie wielki grzech ? :O

Prawda jest taka, że jeśli nie trzeba korzystać z wielowątkowości, to lepiej z niej nie korzystać, bo wprowadza ona dodatkową złożoność do programu. Z tego, co zdążyłem zaobserwować, to w większości typowych aplikacji webowych bardzo mało się z tego korzysta i często większość rzeczy jest obsłużona pod spodem przez różne frameworki i biblioteki. W praktyce z programowaniem wielowątkowym spotkałem się chyba głównie w projektach androidowych, bo tam bez tego ani rusz, jak już kolega wcześniej w tym wątku pisał. Wszystkie operacje typu requesty sieciowe, odczyt/zapis do pliku/bazy lub dowolna inna operacja o niedeterministycznym czasie trwania musi być obsłużona asynchronicznie, aby aplikacja działała płynnie. Dochodzi do tego jeszcze Activity Lifecycle i kilka innych tematów.

Jeśli chodzi o Reactive Programming, to jest to po prostu nic innego, jak warstwa abstrakcji dla niskopoziomowego programowania wielowątkowego. Programowanie współbieżne jest trudne i łatwo się w nim pogubić. Reactive Programming trochę upraszcza temat i bierze na klatę niskopoziomowe tematy wystawiając nam przy tym swoje API. Niestety to API nie jest łatwe i trzeba poświęcić trochę czasu na jego opanowanie, ale później dużo łatwiej jest napisać czytelny, utrzymywalny, testowalny i stabilny program, niż rzeźbiąc kod ręcznie na niższym poziomie. Nie wiem, jak Wy, ale ja bym tego lepiej nie ogarnął, niż np. Ben Christensen albo Erik Meijer.

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