CodeGym /Blog Jawa /Acak /Ngatur Utas. Tembung kunci molah malih lan cara ngasilake...
John Squirrels
tingkat
San Francisco

Ngatur Utas. Tembung kunci molah malih lan cara ngasilaken ().

Diterbitake ing grup
Hi! Kita terus sinau babagan multithreading. Dina iki kita bakal ngerti volatiletembung kunci lan yield()cara. Ayo nyilem :)

Tembung kunci sing molah malih

Nalika nggawe aplikasi multithreaded, kita bisa nemoni rong masalah serius. Kaping pisanan, nalika aplikasi multithreaded mlaku, benang sing beda-beda bisa nyimpen nilai-nilai variabel (kita wis ngomong babagan iki ing pawulangan kanthi irah-irahan 'Using volatile' ). Sampeyan bisa duwe kahanan ing ngendi siji thread ngganti nilai variabel, nanging thread kapindho ora weruh owah-owahan, amarga iku bisa digunakake karo salinan cache sawijining variabel. Alami, akibate bisa serius. Upaminipun punika dudu sembarang variabel lawas nanging rodo imbangan akun bank, kang dumadakan wiwit acak mlumpat munggah lan mudhun :) Sing ora muni kaya fun, tengen? Kapindho, ing Jawa, operasi maca lan nulis kabeh jinis primitif,longdouble, iku atom. Contone, yen sampeyan ngganti nilai variabel inting siji utas, lan ing thread liyane sampeyan maca nilai variabel kasebut, sampeyan bakal entuk nilai sing lawas utawa sing anyar, yaiku nilai sing diasilake saka owah-owahan kasebut. ing thread 1. Ora ana 'nilai penengah'. Nanging, iki ora bisa digunakake karo longs lan doubles. Kenging punapa? Amarga dhukungan lintas-platform. Elingi ing tingkat wiwitan sing kita ujar yen prinsip pedoman basa Jawa yaiku 'nulis sepisan, mlayu ing endi wae'? Tegese dhukungan lintas platform. Ing tembung liyane, aplikasi Java mlaku ing kabeh platform beda. Contone, ing sistem operasi Windows, macem-macem versi Linux utawa MacOS. Iku bakal mbukak tanpa alangan ing kabeh mau. Bobot ing 64 bit,longdoubleminangka primitif 'paling abot' ing Jawa. Lan platform 32-bit tartamtu mung ora ngetrapake maca lan nulis atom variabel 64-bit. Variabel kasebut diwaca lan ditulis ing rong operasi. Kaping pisanan, 32 bit pisanan ditulis menyang variabel, banjur 32 bit liyane ditulis. Akibaté, masalah bisa muncul. Siji thread nulis sawetara nilai 64-bit menyang Xvariabel lan nindakake ing rong operasi. Ing wektu sing padha, utas kapindho nyoba maca nilai variabel kasebut lan nindakake ing antarane rong operasi kasebut - nalika 32 bit pisanan wis ditulis, nanging 32 bit kapindho ora. Akibaté, maca nilai penengah, salah, lan kita duwe bug. Contone, yen ing platform kasebut, kita nyoba nulis nomer kasebut menyang 9223372036854775809 kanggo variabel, iku bakal manggoni 64 bit. Ing wangun binar, katon kaya iki: 10000000000000000000000000000000000000000000000000000000001 Utas pisanan wiwit nulis angka menyang variabel. Wiwitane, kasebut nyerat 32 bit pisanan (100000000000000000000000000000000000000000000000000000000000000) banjur kaping 32 bit 32 (00000000000000000000000000001) Lan utas kapindho bisa diselehake ing antarane operasi kasebut, maca nilai penengah variabel (100000000000000000000000000000000), yaiku 32 bit pisanan sing wis ditulis. Ing sistem desimal, angka iki 2.147.483.648. Ing tembung liya, kita mung pengin nulis nomer 9223372036854775809 menyang variabel, nanging amarga operasi iki ora atom ing sawetara platform, kita duwe nomer ala 2,147,483,648, sing metu saka endi wae lan bakal duwe efek sing ora dingerteni. program. Utas kapindho mung maca nilai variabel sadurunge rampung ditulis, yaiku benang ndeleng 32 bit pisanan, nanging ora 32 bit kapindho. Mesthi, masalah iki ora muncul wingi. Jawa ngrampungake karo tembung kunci siji: volatile. Yen kita nggunakakevolatiletembung kunci nalika ngumumake sawetara variabel ing program kita…

public class Main {

   public volatile long x = 2222222222222222222L;

   public static void main(String[] args) {

   }
}
… tegese:
  1. Bakal tansah diwaca lan ditulis kanthi atom. Malah yen iku 64-dicokot doubleutawa long.
  2. Mesin Java ora bakal cache. Dadi sampeyan ora bakal duwe kahanan ing ngendi 10 utas nggarap salinan lokal dhewe.
Dadi, rong masalah sing serius dirampungake kanthi mung siji tembung :)

Metode yield().

Kita wis nliti akeh Threadmetode kelas, nanging ana sing penting sing bakal dadi anyar kanggo sampeyan. Iku yield()cara . Lan nindakake persis apa jenenge! Ngatur Utas.  Tembung kunci sing molah malih lan metode ngasilake () - 2Nalika kita nelpon yieldcara ing thread, iku bener ngomong karo thread liyane: 'Hei, wong lanang. Aku ora ing sembarang utamané cepet-cepet menyang ngendi wae, dadi yen penting kanggo sapa wae sing njaluk wektu prosesor, njupuk - Aku bisa ngenteni. Punika conto prasaja babagan cara kerjane:

public class ThreadExample extends Thread {

   public ThreadExample() {
       this.start();
   }

   public void run() {

       System.out.println(Thread.currentThread().getName() + " yields its place to others");
       Thread.yield();
       System.out.println(Thread.currentThread().getName() + " has finished executing.");
   }

   public static void main(String[] args) {
       new ThreadExample();
       new ThreadExample();
       new ThreadExample();
   }
}
Kita nggawe lan miwiti telung utas kanthi urutan: Thread-0, Thread-1, lan Thread-2. Thread-0diwiwiti luwih dhisik lan langsung ngasilake liyane. Banjur Thread-1diwiwiti lan uga ngasilake. Banjur Thread-2diwiwiti, sing uga ngasilake. Kita wis ora duwe utas maneh, lan sawise Thread-2menehi panggonan pungkasan, panjadwal thread ngandika, 'Hmm, ora ana maneh thread anyar. Sapa sing ana ing antrian? Sapa sing menehi panggonan sadurunge Thread-2? Iku misale jek iku Thread-1. Oke, tegese kita bakal nglilani. Thread-1ngrampungake karyane banjur panjadwal thread nerusake koordinasi: 'Oke, Thread-1rampung. Apa kita duwe wong liya ing antrian?'. Utas-0 ana ing antrian: wis ngasilake papan sadurungeThread-1. Saiki entuk giliran lan mlaku nganti rampung. Banjur panjadwal rampung ngoordinasi utas: 'Oke, Thread-2, sampeyan wis nyerah menyang utas liyane, lan kabeh wis rampung saiki. Sampeyan sing pungkasan ngasilake, mula saiki giliran sampeyan. Banjur Thread-2mlaku nganti rampung. Output console bakal katon kaya iki: Utas-0 ngasilake papan kanggo wong liya. Utas-0 wis rampung dieksekusi. Utas-2 wis rampung dieksekusi. Mesthi, panjadwal thread bisa miwiti thread ing urutan beda (contone, 2-1-0 tinimbang 0-1-2), nanging prinsip tetep padha.

Mengkono-sadurunge aturan

Babagan pungkasan sing bakal kita demek dina iki yaiku konsep ' kedadeyan sadurunge '. Kaya sing wis sampeyan ngerteni, ing Jawa, panjadwal thread nindakake akeh karya sing melu nyedhiakke wektu lan sumber daya kanggo benang kanggo nindakake tugase. Sampeyan uga wis bola-bali ndeleng carane Utas dieksekusi ing urutan acak sing biasane ora bisa kanggo prédhiksi. Lan umume, sawise pemrograman 'sequential' sing ditindakake sadurunge, pemrograman multithreaded katon kaya acak. Sampeyan wis percaya yen sampeyan bisa nggunakake macem-macem cara kanggo ngontrol aliran program multithreaded. Nanging multithreading ing Jawa nduweni siji pilar maneh - aturan 4 ' kedadeyan-sadurunge '. Ngerteni aturan kasebut cukup prasaja. Mbayangno sing kita duwe loro Utas - AlanB. Saben utas iki bisa nindakake operasi 1lan 2. Ing saben aturan, nalika kita ngomong ' A kedaden-sadurunge B ', kita ateges kabeh owah-owahan sing digawe dening thread Asadurunge operasi 1lan owah-owahan asil saka operasi iki katon kanggo thread Bnalika operasi 2dileksanakake lan sesampunipun. Saben aturan njamin yen sampeyan nulis program multithreaded, acara tartamtu bakal kelakon sadurunge liyane 100% wektu, lan ing wektu operasi 2thread Bbakal tansah weruh saka owah-owahan sing thread Adigawe sak operasi 1. Ayo dideleng.

Aturan 1.

Ngeculake mutex kedadeyan sadurunge monitor sing padha dituku dening benang liyane. Aku mikir sampeyan ngerti kabeh ing kene. Yen mutex obyek utawa kelas dipikolehi dening siji utas., Contone, dening thread A, thread liyane (utas B) ora bisa ndarbeni ing wektu sing padha. Sampeyan kudu ngenteni nganti mutex dirilis.

Aturan 2.

Thread.start()Cara kasebut kedadeyan sadurunge Thread.run() . Maneh, ora ana sing angel ing kene. Sampeyan wis ngerti yen kanggo miwiti mbukak kode ing run()cara, sampeyan kudu nelpon start()cara ing thread. Secara khusus, metode wiwitan, dudu run()metode kasebut dhewe! Aturan iki mesthekake yen nilai kabeh variabel sing disetel sadurunge Thread.start()diarani bakal katon ing run()cara kasebut yen wis diwiwiti.

Aturan 3.

Pungkasan metode run()kedadeyan sadurunge bali saka join()metode kasebut. Ayo bali menyang rong utas: Alan B. Kita nyebat join()cara kasebut supaya utas Bdijamin ngenteni rampunge benang Asadurunge nindakake pakaryan. Iki tegese cara obyek A run()dijamin kanggo mbukak nganti pungkasan. Lan kabeh owah-owahan data sing kedadeyan ing run()cara thread Adijamin satus persen bakal katon ing thread Bsawise rampung ngenteni thread Arampung karyane supaya bisa miwiti karya dhewe.

Aturan 4.

Nulis menyang volatilevariabel kedadeyan sadurunge maca saka variabel sing padha. Nalika nggunakake volatiletembung kunci, kita mesthi entuk nilai saiki. Malah karo longutawa double(kita ngandika sadurungé bab masalah sing bisa kelakon kene). Minangka sampeyan wis ngerti, owah-owahan sing digawe ing sawetara utas ora tansah katon ing utas liyane. Nanging, mesthi, ana kahanan sing kerep banget yen prilaku kasebut ora cocog karo kita. Upaminipun kita nemtokake nilai kanggo variabel ing utas A:

int z;

….

z = 555;
Yen Bthread kita kudu nampilake nilai variabel zing console, bisa gampang nampilake 0, amarga ora ngerti babagan nilai sing ditugasake. Nanging Aturan 4 njamin yen kita nyatakake zvariabel kasebut minangka volatile, banjur owah-owahan ing nilai ing siji thread bakal tansah katon ing thread liyane. Yen kita nambahake tembung volatilemenyang kode sadurunge ...

volatile int z;

….

z = 555;
... banjur kita nyegah kahanan ing ngendi thread Bbisa nampilake 0. Nulis kanggo volatilevariabel mengkono sadurunge maca saka wong-wong mau.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION