Article View: pl.comp.lang.java
Article #149862Re: czy wątki mogą świadczyć usługi?
From: Witold Szczerba
Date: Wed, 24 Mar 2010 23:45
Date: Wed, 24 Mar 2010 23:45
53 lines
4703 bytes
4703 bytes
On Mar 21, 5:29 pm, andrzej salwicki <salwi...@gmail.com> wrote: > Czy można w efektywny sposób zaprogramować wątek A tak by pełnił swoje > zadanie i równocześnie był gotów świadczyc usługi? Dokładniej, czy > inne wątki: B, C, ... mogą wywoływać metody publiczne, synchronized > wątku A, powodując chwilowe przerwanie akcji wątku A, wykonanie > wskazanej metody, po czym wątek A kontynuuje swoje obliczenia. > Mam pewne podejrzenia, ale trudno o tym rozstrzygnąć na podstawie JLS. > Za odpowiedź, wszytko jedno pozytywną czy negatywną- ale uzasadnioną - > przeznaczam skrzynkę wina lub ekwiwalent. > Uzasadnienie: > W przypadku podpowiedzi pozytywnej należy podać przykład programu. Np > 'Spooler' - proces rejestruje zgłoszone do druku pliki przy pomocy > metody 'drukuj(plik)' i równocześnie wysyła już zarejestrowane pliki, > po kolei do drukarki. > W przypadku odpowiedzi negatywnej należy podać uzasadnienie, > niekoniecznie w postaci dowodu, ale jakiś intersubiektywny argument > jest konieczny bym uwierzył. Tak już zupełnie podsumowując dyskusję: w Javie takie rozwiązanie o jakim pisze Andrzej (żeby wątki sobie wzajemnie wchodziły w drogę, blokowały się w "dziki" sposób) nie ma absolutnie sensu. Przykładowy Spooler może wyglądać następująco: jest kolejka - coś w rodzaju tablicy/listy/kolejki z synchronizowanym dostępem, może to być wspomniana już nieraz BlockingQueue. Jest też wątek - nazwijmy go usługą, którego zadanie polega na pobieraniu elementów z wspomnianej listy/kolejki. Tak więc nasz wątek odczytuje z kolejki wiadomość - jeśli nic w niej nie ma to zawiesza swoje działanie do momentu, aż coś się w kolejce pojawi. Gdy się pojawi - "ożywa" i wykonuje zadanie, na przykład drukuje plik, gdy skończy drukowanie znowu wraca do początku i czeka aż coś się pojawi. Teraz pozostaje kwestia dostępu do tej usługi z zewnątrz - nic prostszego, wystarczy uzyskać referencję tej listy/kolejki - tej samej, której używa nasz wątek i włożyć do niej komunikat/plik/itp. i... tyle (nasza "usługa" może sama zdefiniować metodę w stylu "drukuj", a w środku tej metody nic innego jak zapakowanie obiektu do listy). Jeśli nasza usługa jest zajęta drukowaniem, komunikat sobie poczeka w kolejce, a jeśli nasza usługa nic nie robi, to weźmie się do roboty jak tylko komunikat/plik zostanie umieszczony w kolejce. Ot - cała filozofia. Pozostaje jedynie kwestia owej synchronizacji kolejki z wątkami - jak wspominano tutaj często - można użyć gotowego BlockingQueue, można sobie samemu takie coś napisać korzystając z podstawowych instrukcji/modyfikatorów języka (vide synchronized/ volatile/java.util.concurrent.*/...), jak ktoś jest ciekawy jak działa BlockingQueue - może sobie zajrzeć w źródła. Innymi słowy - obiekt, który jest odpowiedzialny za drukowanie - wykonuje to drukowanie w swoim wątku, ale to nie oznacza, że jego wszystkie metody są wykonywane w jednym i tym samym wątku - dlatego nie ma różnicy: czy klient dostaje referencje do listy i umieszcza w niej komunikat, czy może klient dostaje referencję bezpośrednio do usługi i wykonuje jej metodę #dodajDoKolejki(komunikat). Ważne jest tylko odpowiednie synchronizowanie (mediacja pomiędzy różnymi wątkami) - coś co BlockingQueue ma "out of the box", dlatego nazwa tej klasy cieszy się w tym wątku taką popularnością :)
Technical Details
Message-ID:
<9aa774c6-0636-486a-879c-a008238b8e2d@x12g2000yqx.googlegroups.com>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.glorb.com!postnews.google.com!x12g2000yqx.googlegroups.com!not-for-mailReferences:
<4c3b4f20-3f62-4e54-9e3c-298e4ea6c3e5@g10g2000yqh.googlegroups.com>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.glorb.com!postnews.google.com!x12g2000yqx.googlegroups.com!not-for-mail From: Witold Szczerba <pljosh.mail@gmail.com> Newsgroups: pl.comp.lang.java Subject: Re: czy wątki mogą świadczyć usługi? Date: Wed, 24 Mar 2010 16:45:02 -0700 (PDT) Organization: http://groups.google.com Lines: 68 Message-ID: <9aa774c6-0636-486a-879c-a008238b8e2d@x12g2000yqx.googlegroups.com> References: <4c3b4f20-3f62-4e54-9e3c-298e4ea6c3e5@g10g2000yqh.googlegroups.com> NNTP-Posting-Host: 83.23.29.106 Mime-Version: 1.0 X-Trace: posting.google.com 1269474303 5203 127.0.0.1 (24 Mar 2010 23:45:03 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Wed, 24 Mar 2010 23:45:03 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: x12g2000yqx.googlegroups.com; posting-host=83.23.29.106; posting-account=gnHnDQoAAABAt-cdgg6OG0gvpEhXZTSx User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7,gzip(gfe),gzip(gfe) Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit