Názory k článku
Síťování v Javě: Úvod
select()
celé vláknoCopak se v Jave neda pouzit neco na zpusob syscallu select(2)? Tzn. funkce/trida ktere predam pole streamu ze kterych chci cist (stdin, net) a ona bude cekat az do doby nez jeden z tech streamu ma k dispozici data. Pak mi rekne ktery to byl a ja muzu vesele pokracovat. To je, rekl bych, mnohem jednodussi a standardnejsi pristup nez machrovani s threadama...
Re: select()
celé vlákno(Včera jsem to vyčetl z jedné knížky :) )
Re: select()
celé vláknoRe: select()
celé vláknoA potom, nejde ani tak o rychlost, jako o jednoduchost kodu (s thready musite davat bacha, co musi byt synchronized atp.).
Re: select()
celé vláknoTak to je určitě rozdíl.
A potom, nejde ani tak o rychlost, jako o jednoduchost kodu (s thready musite davat bacha, co musi byt synchronized atp.)To bych ani neřekl. Přece jen se každý thread stará o své vlastní spojení a s ostatními "spojovacími" vlákny nemá důvod komunikovat. Jediné, co je nutné synchornizovat (ale to vždycky), jsou objekty společné všem vláknům. Psal jsem (přiznávám, jednoduchý) komunikační program pro LAN (v C#) a pro každého uživatele, kterého jste měl v seznamu, běžel jeden thread, který zjisťoval jeho stav (tj. to vlákno bylo skoro pořád ve stavu sleep) + další vlákna pro otevřená okna, kde jste si chatoval s tím daným uživatelem. Rozdělení do threadů bylo velmi jednoduché a přineslo daleko větší možnosti. Max počet vláken toho programu co jsem zkoušel byl 60, což není vůbec moc.
Re: select()
celé vláknoRe: select()Re: select()
celé vláknoRe: select()Re: select()
celé vláknoPouze mě zaráží, že se "tolik" píše proti použití vlákna na každé spojení. Nic víc nic míň.
I procesory x86 udělali hodně velký pokrok, co se týče zpracování mnoha procesů (např. rychlejší přepínání kontextu, masivní paralelismus uvnitř CPU -- na GPU to ještě nemá, ale snad časem, "inteligetní" prefetch do cache). A bude se to zlepšovat. Budou přibývat jádra, zvětšovat se cache, měnit se celá architektura PC (AMD například používá NUMA ve svých multiprocesorových řešeních, místo "klasického" SMP na FSB jak má Intel). Tak nevidím důvod, proč nemít v programu třeba 512 vláken. Možná se mýlím a rád se nechám poučit.
Re: select()Re: select()
celé vláknoNa servri je pouzitie select() nevyhnutnostou. Specialne co sa tyka triedy java.net.Socket ma problem ze za urcitych okolnosti nie je mozne rozlisit ze socket bol z druhej strany zatvoreny (programovo alebo z dovodu sietovej chyby) takze takto napisany server po case lahne.
Nadmerna zataz (sietova,...) zlozi akykolvek server. V dobrom servri ktory ma byt odolny aj proti DoS utoku musis mat dobre vyriesene fronty, cakacie stavy a aj odmietanie poziadaviek.
Re: select()
celé vláknoS temi vlakny je spis problem ten, ze pokud bude tech komunikaci vice, pak nam vlakna budou narustat a narustat.
Druha vec je ta, ze uvedeny kod se netyka Telnet klienta, ale TCP trubky. Telnet zpracovava signaly typu Ctrl-C, Ctrl-Z a podobne veci, ktere by zarizeni typu TTY melo umet.
Re: select()
celé vláknoSamozřejmě, slabinou tohoto způsobu je špatná škálovatelnost.
Re: select()
celé vláknoVzhledem k tomu, ze melo jit o jednoduchou ukazku prace se siti, tak je to imho v pohode, az budete mit server obsluhujici tisic spojeni najednou, tak jsou selecty na miste. A co se standardnosti tyce, tezko rict, ale co jsem videl, tak mi prijde, ze se tenhle pristup opravdu hodne pouziva, prace s vlakny je v Jave jednoducha a dokud jich staci par...
Re: select()
celé vláknoclose()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoShodou náhod zrovna psal někdo na builder.cz, že má ORA-01000 musel jsem se začít smát :D
Re: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoPoradíte?
Re: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoTakže, představme si výstup na konsoli z nějakého prográmku na zpracování speciálních obrázků:
$imageprocess: -i image.bin -offt image.fft -ostats image.stats
Processing Image
[Warning] Image file is in deprecated format, version 0.5.
[Warning] Image does not contain statistical information.
Starting Fast Fourier Transformation...
[Warning] Image size is not compatible with FFT, cropping image.
Done
Gathering Statistical Information...
Done
image.fft Saved
image.stats Saved
Takhle by to vypadalo po vypisu všeho do System.out. A to jsem vzal ještě mírnější versi, kde nenastaly ty "velké chyby", kterých může být klidně přes sto. Uživatel ví, že obrázek není čtvercový a že se bude ořezávat, uživatel ví, že v obrázku staré verse nejsou statistické informace. Proto preferuje výpis:
$imageprocess: -i image.bin -offt image.fft -ostats image.stats 2&>/dev/null
Processing Image
Starting Fast Fourier Transformation...
Done
Gathering Statistical Information...
Done
image.fft Saved
image.stats Saved
Zdá se mi to přehlednější, vám ne? A ten váš very simple grep není všude a ne každý s ním umí pracovat. Přesměrovnání do souboru ano.
Re: close()
celé vláknoRe: close()
celé vláknoRe: close()
celé vláknoTak jak tak, chybové hlášení patří na standardní chybový výstup. Na tom trvám.
Re: close()
celé vláknoRe: close()
celé vláknoSamozrejme ze chyby patria do file descriptora 2 aby sa dali oddelit alebo do samostatneho error kanala v logovacom baliku.
Re: close()
celé vláknoRe: close()
celé vláknoDedicnost?
celé vláknoAd close() - namet na flame ;) : tady to neni az tak moc videt, ale k cemu je mi pak cely ten system s garbage collectorem, kdyz se o lifetime objektu (coz v tomto pripade defakto close je) musim starat sam? To sme pak nekde zpatky pred 20ti lety na strukturovanem programovani :-/
Re: Dedicnost?
celé vlákno1) Socket (nebo file handle) je zdroj operačního systému a garbage collector se ho tedy bohužel netýká.
2) Patřičné konkrétní třídy samozřejmě mají metodu finalize(), ve které se close() volá.
Re: Dedicnost?
celé vláknoRe: Dedicnost?
celé vláknoRe: Dedicnost?
celé vláknoRe: Dedicnost?
celé vláknoRe: Dedicnost?
celé vláknoJiste, Java neni na kdejakou utilitku, je to "nastroj" pro velke masiny, kde je (casto) vykonu na rozdaj. Trebaaaaa - hm, treba mobil! :-D
PS: V Jave ani Basicu nekoduju, protoze jsem si zvykl delat design v jistem smyslu objektovy. Neberte to jako osobni utok, jen se strasne bavim na ucet <no flame please> tech cvoku co Javu vymysleli a tech, co si mysli, ze je to v poradku. </no flame please>
Re: Dedicnost?
celé vláknohmm
celé vláknoblesk z nebe, problem bude, ze a ted nechci soudit, jim tady stejne nikdo
poradne nerozumi, vcetne me. Bez urazky.
Proti selectu(poolu) taky nemam nic, kdyz je dobre pouzit je tez fajn.
pochopitelne vyuzivat stderr, o tom zadna. stejne jako uvolnovat spojeni,
to vi kazdy, flush() je super bez diskuze, klasicky duraz na cem bazirujou na
skole, kontrola navratovych hodnot a to i u takoveho close() !
Osobne nemam rad Javu, proto bijte ji dokud nezdechne. Jen zertuji,
sitove programovani v Jave je stejne useless, ping v ni nenapisete, tak
cemu to. Enjoy JDBC(silene rozhrani). bytecode is useless.
42. A co slysi webmaster ve vlaku? TD TD TD, http://hovnocucy.predseda.com/; init 0
Re: hmm
celé vlákno- Multithreading v klientskych aplikaciach nie je problem. 2-6 threadov je absolutne v pohode. Na problemy na dnesnom zeleze narazite tak pri 80-140 threadoch. Threadmi treba setrit v server aplikaciach.
- NIO a select v jave ma jeden vedlajsi problem. Suvisi to z blokovacimi readmi a serializaciou.
- close() je bez diskusie ale musi byt vhodne pouzite. Tiez to nie je celkom logicke. Ucebnicovy priklad:
FileInputStream fInput=new FileInputStream("aa.txt");
try {
fInput.....
} catch (Exception ex) {
ex.printStackTrace();
} finally {
fInput.close();
}
Kedze ale aj new FileInputStream moze vyhodit FileNotFoundException tak najlepsie to bude vyzerat asi takto:
FileInputStream fInput=null;
try {
fInput=new FileInputStream("aa.txt");
fInput.....
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fInput != null) {
fInput.close();
}
}
- A na zaver aj odkaz pre ostatnych: "Na javu mi nesahajte".
Re: hmm
celé vlákno:-D Aha, tak to jo. To jo. To je v pohode. :-DDD
Re: hmm
celé vláknoRe: hmm
celé vláknoAno, vesela kopa jsem, protoze je patek a bavime se o Jave. To nejde prezit jinak nez s usmevem.
Hezky den. :-)
Re: hmm
celé vláknotry {
fout = new FileOutputStream("aa.txt");
log1 = SomeLogger.createUsingStream(fout);
log2 = SomeLogger.createUsingStream(fout);
create more objects using fout, log1, log2
}
catch (whatever) {
}
finally {
fout.close();
throw FailedInitialization();
}
... some stuff, use created objects in threads, ...
A kdo ted zavola close() na fout? Tohle vyresil napr. COM uz pred 15-20ti lety ;)
Re: hmm
celé vláknoRe: hmm
celé vláknoV principu jde o to, ze ten fout je sdileny vice entitami a neexistuje (nechce existovat) nekdo, kdo rekne, ze fout se muze zavrit, protoze uz ho nikdo nepouziva.
Re: hmm
celé vláknoAle vazne - moooc hezky jsi to napsal, Palo asi moc nepochopil, kde je zakopany hafak.
SSH?
celé vláknoOtazocka
celé vlákno...
finally {
os.close();
}
...
tak pri preklade mi to hadze chybu:
Telnet.java:108: unreported exception java.io.IOException; must be caught or declared to be thrown
os.close();
^
1 error
Som lama, poradte ;)
Peter
Re: Otazocka
celé vlákno{
if (os != null)
try {os.close();} catch (Exception e){}
}

