Hinnavaatlus
:: Foorum
:: Uudised
:: Ärifoorumid
:: HV F1 ennustusvõistlus
:: Pangalink
:: Telekavad
:: HV toote otsing
|
|
autor |
|
tonism
Kreisi kasutaja
liitunud: 30.06.2002
|
14.02.2012 17:37:47
Java threadidevaheline suhtlemine |
|
|
Mul on huvi panna Java threadid omavahel suhtlema. Programmi ülesehitus on mul ca järgmine:
main {
- teeb LogicThreadi (siin hoitakse ja arvutatakse kõiki väärtusi)
- teeb RenderThreadi (siin joonistatakse)
- tulevikus teeb veel threade, mis peavad LogicThreadiga suhtlema
}
RenderThread extends Canvas implements Runnable {
- siin joonistatakse
InputHandler implements Key&Mousestuff { - siin korjatakse kokku kasutaja sisestused ja saadetakse LogicThreadile nendega tegelemiseks }
}
LogicThread implements Runnable {
- siin arvutatakse kõik vajaminev
}
|
Nimelt vaja oleks, et Renderdaja saaks LogicThreadi käest informatsiooni ning LogicThread saaks InputHandleri käest infot. InputHandler on RenderThreadi all, kuna sain selle attachida antud juhul Canvase külge (milleks ongi RenderThread).
Minu praegune mõte on LogicThreadi sisse teha sünkroniseeritud getInput(), setInput() ja getData() vastavad inputide ning muude andmete saamiseks ja edastamiseks, kuid ma ei tea, kas see on parim mõte v kuidas seda suhtlust üldse kõige paremini teha.
|
|
Kommentaarid: 5 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
5 |
|
tagasi üles |
|
 |
serk
HV kasutaja
liitunud: 24.05.2003
|
14.02.2012 21:10:41
|
|
|
Synchronizeiga saad seda teha küll(hreadide vahelist suhtlust). Häirib sind selle juures midagi?
|
|
Kommentaarid: 8 loe/lisa |
Kasutajad arvavad: |
   |
:: |
1 :: |
0 :: |
7 |
|
tagasi üles |
|
 |
tonism
Kreisi kasutaja
liitunud: 30.06.2002
|
14.02.2012 23:12:02
|
|
|
Pigem uurin, et milliseid lahendusi oleks mõistlik kasutada. Olen piisavalt n00b, et tahaks kaaluda erinevate lahenduste vahel.
|
|
Kommentaarid: 5 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
5 |
|
tagasi üles |
|
 |
lehm2
Kreisi kasutaja

liitunud: 19.09.2004
|
14.02.2012 23:25:18
|
|
|
Sisuliselt kui lõimeid kasutada, siis ole ettevaatlik kuna sünkroniseerimine blokeerib hetkeks resurssid ära ning kui see logic thread hoiab resursse liiga kaua kinni siis teised nälgivad, sinu näite puhul RenderThread. Threadi teema on pikk ja lai, ühesõnaga lukusta võimalikult vähe ning lühikest aega. Loe siit juurde näiteks http://en.wikipedia.org/wiki/Lock_(computer_science)
_________________ Piilu siia, progreja!
Vajad abi Node.JS-ga ?
Võta ühendust ! |
|
Kommentaarid: 15 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
13 |
|
tagasi üles |
|
 |
Fukiku
Kreisi kasutaja

liitunud: 06.11.2003
|
15.02.2012 10:05:06
|
|
|
Ega üldiselt jah - muud teha pole, kui mingi andmeobjekt kõigile threadidele kättesaadavaks teha ja selle ligipääsu meetodid või mingid osad neist ära sünkroniseerida. Samas palju pornot tuleb mitmelõimelises rakenduses kindlasti. Olles kunagi ühte üle keskmise keerukat serverit üritanud nullist valmis progeda, siis seal suurel koormusel kiilus asi kuhugi ikka lõpuks kinni. Paraku ei olnud enam aega ega motivatsiooni seda kõike sirgeks triikida.
_________________ Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist. |
|
Kommentaarid: 2 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
2 |
|
tagasi üles |
|
 |
YberCyrus
HV vaatleja
liitunud: 27.02.2010
|
|
tagasi üles |
|
 |
tonism
Kreisi kasutaja
liitunud: 30.06.2002
|
15.02.2012 15:25:00
|
|
|
Puusalt tulistades tundub concurrent muutujate/collectionite kasutamine antud juhul isegi mõistlikum kuna LogicThread peab hakkama suhtlema paljude "väiksemate" threadidega. Sünkroniseerimine võib sellisel juhul tõepoolest üleliigselt koormavaks osutuda.
RenderThread, näiteks, käib andmeid küsimas jämedalt iga 17 ms tagant. Teised threadid tõenäoliselt isegi veelgi harvem. Seevastu aga InputHandler peaks iga nupuvajutuse (ja nupu lahtilaskmise) puhul koheselt sellest teavitama LogicThreadi, kes siis jooksvalt peab omad järeldused sellest tegema.
Küsin veel, et kas on õige lähenemine InputHandler tekitada RenderThreadi alla? Esialgu tahtsin täiesti sõltumatuid threade jooksma panna, kuid mulle tundub, et Inputide handlimiseks peab selle siiski otseselt siduma mingi UI-ga (Canvas, Applet, etc), mis mõneti tundub ka loogiline.
|
|
Kommentaarid: 5 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
5 |
|
tagasi üles |
|
 |
Fukiku
Kreisi kasutaja

liitunud: 06.11.2003
|
16.02.2012 12:10:23
|
|
|
tonism kirjutas: |
Puusalt tulistades tundub concurrent muutujate/collectionite kasutamine antud juhul isegi mõistlikum kuna LogicThread peab hakkama suhtlema paljude "väiksemate" threadidega. Sünkroniseerimine võib sellisel juhul tõepoolest üleliigselt koormavaks osutuda. |
Kui nüüd täpne olla, siis ega sa ju sünkroniseerimisest ei pääse - see on sinu eest kapoti all ära tehtud. Lihtsam on ainult oma koodi kirjutada, sest sa ei pea sünkromuredega ise tegelema nii palju ja seega on tõenäoliselt vähem vigasid koodis.
tsitaat: |
RenderThread, näiteks, käib andmeid küsimas jämedalt iga 17 ms tagant. Teised threadid tõenäoliselt isegi veelgi harvem. Seevastu aga InputHandler peaks iga nupuvajutuse (ja nupu lahtilaskmise) puhul koheselt sellest teavitama LogicThreadi, kes siis jooksvalt peab omad järeldused sellest tegema.
Küsin veel, et kas on õige lähenemine InputHandler tekitada RenderThreadi alla? Esialgu tahtsin täiesti sõltumatuid threade jooksma panna, kuid mulle tundub, et Inputide handlimiseks peab selle siiski otseselt siduma mingi UI-ga (Canvas, Applet, etc), mis mõneti tundub ka loogiline. |
Hm.. tekkis küsimus - sa ütled, et sul thread käib iga 17ms tagant andmeid küsimas? Kas sa oled tõesti siin rakendanud busy waiting meetodit? See on mõttetu ressursi raiskamine ning enamasti ei ole asjakohane. Parem oleks mingi sõnumipõhine lahendus siia tekitada - üks lõim laob puhvrisse sõnumeid andmetega, teine loeb neid sealt. Kui sõnumeid pole siis lugev thread ootab kuni uue sõnumi tekkimiseni, mitte ei käi tsükliga tühja kellamas. Käsitsi ehitades uuri wait() ja notify() meetodeid Object klassi küljes, aga kindlasti leiab selle jaoks ka mingeid valmislahendusi.
Mis puutub InputHandlerisse .. siis seda ei ole sul põhimõtteliselt vaja ühegi enda lõimegaju siduda, sest kui sa selle handleri addXxxListener meetoditega oma GUI komponendile külge paned, siis toimetab selle handleriga edaspidi juba nii ehk nii Swingi või AWT eventhandler lõim, mis õigeid handleri meetodeid käivitab, seega ei ole sisulist vahet millisest lõimest sa sooritad addXxxListener tegevused - lõpptulemus on sama.
_________________ Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist. |
|
Kommentaarid: 2 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
2 |
|
tagasi üles |
|
 |
tonism
Kreisi kasutaja
liitunud: 30.06.2002
|
17.02.2012 21:39:38
|
|
|
Fukiku kirjutas: |
Kui nüüd täpne olla, siis ega sa ju sünkroniseerimisest ei pääse - see on sinu eest kapoti all ära tehtud. Lihtsam on ainult oma koodi kirjutada, sest sa ei pea sünkromuredega ise tegelema nii palju ja seega on tõenäoliselt vähem vigasid koodis. |
Seda enam tundub parem mõte
tsitaat: |
Hm.. tekkis küsimus - sa ütled, et sul thread käib iga 17ms tagant andmeid küsimas? Kas sa oled tõesti siin rakendanud busy waiting meetodit? See on mõttetu ressursi raiskamine ning enamasti ei ole asjakohane. Parem oleks mingi sõnumipõhine lahendus siia tekitada - üks lõim laob puhvrisse sõnumeid andmetega, teine loeb neid sealt. Kui sõnumeid pole siis lugev thread ootab kuni uue sõnumi tekkimiseni, mitte ei käi tsükliga tühja kellamas. Käsitsi ehitades uuri wait() ja notify() meetodeid Object klassi küljes, aga kindlasti leiab selle jaoks ka mingeid valmislahendusi. |
Kui ma sellest busy waitingust õigesti aru saan siis ei. Threadi ajastamine toimub nii:
public void run() {
lastDurration = System.currentTimeMillis();
process();
lastDurration = Math.abs(lastDurration - System.currentTimeMillis());
try {
if (lastDurration > 1000L / runSpeed) {
System.err.println(getClass() + ": " + (lastDurration - 1000L / runSpeed) + " ms deficit!");
} else {
Thread.sleep(1000L / runSpeed - lastDurration);
}
}
catch (InterruptedException e) { e.printStackTrace(); }
} |
|
|
Kommentaarid: 5 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
5 |
|
tagasi üles |
|
 |
YberCyrus
HV vaatleja
liitunud: 27.02.2010
|
19.02.2012 15:54:25
|
|
|
Fukiku kirjutas: |
tonism kirjutas: |
Puusalt tulistades tundub concurrent muutujate/collectionite kasutamine antud juhul isegi mõistlikum kuna LogicThread peab hakkama suhtlema paljude "väiksemate" threadidega. Sünkroniseerimine võib sellisel juhul tõepoolest üleliigselt koormavaks osutuda. |
Kui nüüd täpne olla, siis ega sa ju sünkroniseerimisest ei pääse - see on sinu eest kapoti all ära tehtud. Lihtsam on ainult oma koodi kirjutada, sest sa ei pea sünkromuredega ise tegelema nii palju ja seega on tõenäoliselt vähem vigasid koodis. |
Ma küll pole ise concurrent package kapotialust uurinud aga pigem väidaks, et concurrency package eesmärk on pakkuda non-blocking viise multithreadinguks ehk siis sünkroniseerimine (mis hoiab locki mingil objektil kuni 1 thread oma töö lõpetab) pole seal implementeeritud kuna sünkroniseerimine on blocking algoritm. Leidsin huvitava artikli sellekohta: http://www.ibm.com/developerworks/java/library/j-jtp04186/index.html
|
|
tagasi üles |
|
 |
Fukiku
Kreisi kasutaja

liitunud: 06.11.2003
|
20.02.2012 11:10:10
|
|
|
tonism kirjutas: |
Fukiku kirjutas: |
Kui nüüd täpne olla, siis ega sa ju sünkroniseerimisest ei pääse - see on sinu eest kapoti all ära tehtud. Lihtsam on ainult oma koodi kirjutada, sest sa ei pea sünkromuredega ise tegelema nii palju ja seega on tõenäoliselt vähem vigasid koodis. |
Seda enam tundub parem mõte
tsitaat: |
Hm.. tekkis küsimus - sa ütled, et sul thread käib iga 17ms tagant andmeid küsimas? Kas sa oled tõesti siin rakendanud busy waiting meetodit? See on mõttetu ressursi raiskamine ning enamasti ei ole asjakohane. Parem oleks mingi sõnumipõhine lahendus siia tekitada - üks lõim laob puhvrisse sõnumeid andmetega, teine loeb neid sealt. Kui sõnumeid pole siis lugev thread ootab kuni uue sõnumi tekkimiseni, mitte ei käi tsükliga tühja kellamas. Käsitsi ehitades uuri wait() ja notify() meetodeid Object klassi küljes, aga kindlasti leiab selle jaoks ka mingeid valmislahendusi. |
Kui ma sellest busy waitingust õigesti aru saan siis ei. Threadi ajastamine toimub nii:
Spoiler 
java:
|
public void run() { lastDurration = System. currentTimeMillis(); process(); lastDurration = Math. abs(lastDurration - System. currentTimeMillis()); try { if (lastDurration > 1000L / runSpeed) { System. err. println(getClass () + ": " + (lastDurration - 1000L / runSpeed ) + " ms deficit!"); } else { Thread. sleep(1000L / runSpeed - lastDurration ); } } }
|
|
Kui nüüd selle busy waiting käsitlusega edasi minna, siis küsimus taandub sel juhul sellele, et mis toimub process() meetodi kõhus. Kui sul seal sees on ikkagi mingine if-lause, mis kontrollib, et kas sisend on olemas ja sisendi puudumisel kohe returnib, siis see on ju busy waiting selle kõige klassikalisemas mõttes - käiakse perioodiliselt kellamas kuskil, et kas on midagi teha või mitte. Või on sul kuidagi garanteeritud, et igakord, kui process() meetod välja kutsutakse, on tal mingit sisulist ja efektiivset tegevust?
Soovitaksin siiski uurida ka Object.wait() ja Object.notify() kasutust. Hea lugemine sel teemal võiks olla näiteks ka Bruce Eckel'i "thinking in Java". Peaasjalikult siis peatükk 13, kus need teemad ette võetakse. Raamat põhineb küll Java 1.4 peal aga üldpõhimõtted on ka uuemate Java versioonide peal samad.
_________________ Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist. |
|
Kommentaarid: 2 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
2 |
|
tagasi üles |
|
 |
|