JavaRush /Blog Jawa /Random-JV /Manajemen aliran. Tembung kunci molah malih lan cara ngas...

Manajemen aliran. Tembung kunci molah malih lan cara ngasilaken ().

Diterbitake ing grup
Hello! Kita terus sinau multithreading, lan dina iki kita bakal kenal karo tembung kunci anyar - molah malih lan cara ngasilaken (). Ayo ngerteni apa iku :)

Kata kunci molah malih

Nalika nggawe aplikasi multi-Utas, kita bisa ngadhepi rong masalah serius. Kaping pisanan, sajrone operasi aplikasi multi-threaded, macem-macem benang bisa nyimpen nilai variabel (kita bakal ngomong luwih akeh babagan iki ing kuliah "Nggunakake molah malih" ). Sampeyan bisa uga yen siji thread ngganti nilai variabel, nanging sing nomer loro ora weruh owah-owahan iki amarga nggarap salinan variabel sing di-cache dhewe. Alami, akibate bisa serius. Mbayangno sing iki ora mung sawetara jenis "variabel", nanging, contone, imbangan saka kertu bank, kang dumadakan wiwit acak mlumpat bali lan kasebut :) Ora banget penake, tengen? Kapindho, ing Jawa, operasi maca lan nulis ing lapangan kabeh jinis kajaba longlan doubleatom. Apa atomicity? Contone, yen sampeyan ngganti nilai variabel ing siji thread int, lan ing thread liyane sampeyan maca nilai variabel iki, sampeyan bakal entuk nilai sing lawas utawa sing anyar - sing katon sawise owah-owahan ing thread 1. Ora "opsi penengah" bakal katon ana Mungkin. Nanging, iki ora bisa karo longlan . doubleKenging punapa? Amarga iku cross-platform. Apa sampeyan kelingan carane kita ngandika ing tingkat pisanan sing prinsip Jawa "ditulis sepisan, dianggo nang endi wae"? Iki cross-platform. Yaiku, aplikasi Java mlaku ing platform sing beda-beda. Contone, ing sistem operasi Windows, macem-macem versi Linux utawa MacOS, lan ing endi wae aplikasi iki bakal bisa digunakake kanthi stabil. longlan double- primitif paling "abot" ing Jawa: bobote 64 bit. Lan sawetara platform 32-bit mung ora ngetrapake atomicity maca lan nulis variabel 64-bit. Variabel kasebut diwaca lan ditulis ing rong operasi. Pisanan, 32 bit pisanan ditulis menyang variabel, banjur liyane 32. Mulane, ing kasus iki masalah bisa muncul. Siji thread nulis sawetara nilai 64-bit menyang variabelХ, lan dheweke nindakake "ing rong langkah". Ing wektu sing padha, utas kapindho nyoba maca nilai variabel iki, lan nindakake ing tengah, nalika 32 bit pisanan wis ditulis, nanging sing nomer loro durung ditulis. Akibaté, maca nilai penengah, salah, lan ana kesalahan. Contone, yen ing platform kasebut kita nyoba nulis nomer menyang variabel - 9223372036854775809 - bakal manggoni 64 bit. Ing wangun binar bakal katon kaya iki: 10000000000000000000000000000000000000000000000000000000000001 Utas pisanan bakal miwiti nulis angka iki menyang variabel, lan bakal nulis 000000000000000000000000000000000000000 000000 00000 lan banjur kaping pindho 32: 00000000000000000000000000000001 Lan benang kapindho bisa nglebokake celah kasebut lan maca nilai penengah variabel - 10000000000000000000000000000000, 32 bit pisanan sing wis ditulis. Ing sistem desimal, nomer iki padha karo 2147483648. Yaiku, kita mung pengin nulis nomer 9223372036854775809 dadi variabel, nanging amarga operasi iki ing sawetara platform ora atom, kita entuk nomer "kiwa" 2147483648 , sing kita ora perlu, metu saka ngendi wae. lan ora dingerteni carane bakal mengaruhi operasi program. Utas kapindho mung maca nilai variabel sadurunge pungkasane ditulis, yaiku, ndeleng 32 bit pisanan, nanging ora 32 bit kapindho. Masalah kasebut, mesthi, ora muncul wingi, lan ing Jawa ditanggulangi mung nggunakake siji tembung kunci - volatile . Yen kita ngumumake sawetara variabel ing program kita kanthi tembung volatile ...
public class Main {

   public volatile long x = 2222222222222222222L;

   public static void main(String[] args) {

   }
}
…tegese:
  1. Bakal tansah diwaca lan ditulis kanthi atom. Sanajan 64-bit doubleutawa long.
  2. Mesin Java ora bakal cache. Dadi kahanan nalika 10 utas bisa digunakake karo salinan lokal ora kalebu.
Iki carane loro masalah serius ditanggulangi ing siji tembung :)

metode yield().

Kita wis ndeleng akeh metode kelas Thread, nanging ana siji penting sing bakal dadi anyar kanggo sampeyan. Iki minangka metode yield() . Diterjemahake saka basa Inggris minangka "give in." Lan sing persis apa cara! Manajemen aliran.  Tembung kunci sing molah malih lan metode ngasilake () - 2Nalika kita nelpon cara ngasilake ing thread, iku bener ngandika kanggo thread liyane: "Oke, wong, aku ora cepet-cepet tartamtu, dadi yen penting kanggo sapa wae kanggo njaluk wektu CPU, njupuk, aku ora urgent.” Punika conto prasaja babagan cara kerjane:
public class ThreadExample extends Thread {

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

   public void run() {

       System.out.println(Thread.currentThread().getName() + "give way 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();
   }
}
We sequentially nggawe lan miwiti telung Utas - Thread-0, Thread-1lan Thread-2. Thread-0diwiwiti dhisik lan langsung menehi dalan kanggo wong liya. Sawise iku diwiwiti Thread-1, lan uga menehi dalan. Sawisé iku, iku wiwit Thread-2, kang uga rodok olo. Kita ora duwe utas maneh, lan sawise Thread-2sing pungkasan wis nyerah, panjadwal thread katon: "Dadi, ora ana benang anyar, sapa sing ana ing antrian? Sapa sing pungkasan nyerahake papan sadurunge Thread-2? Aku iku Thread-1? Oke, supaya rampung. Thread-1nindakake tugas nganti pungkasan, sawise jadwal thread terus koordinasi: "Oke, Thread-1 wis rampung. Apa kita duwe wong liya ing baris?" Ana Utas-0 ing antrian: dheweke langsung nyerah sadurunge Utas-1. Saiki prakara wis teka marang dheweke, lan dheweke ditindakake nganti pungkasan. Sawisé iku panjadwal rampung koordinasi thread: "Oke, Thread-2, sampeyan wis menehi dalan kanggo thread liyane, kabeh wis bisa. Sampeyan sing pungkasan menehi dalan, mula saiki giliran sampeyan. Sawise iki, Thread-2 mlaku nganti rampung. Output console bakal katon kaya iki: Utas-0 menehi dalan kanggo wong liya Utas-1 menehi dalan kanggo wong liya Utas-2 menehi wong liya Utas-1 wis rampung dieksekusi. Utas-0 wis rampung dieksekusi. Utas-2 wis rampung dieksekusi. Penjadwal thread, mesthi, bisa mbukak thread ing urutan beda (contone, 2-1-0 tinimbang 0-1-2), nanging prinsip padha.

Mengkono-sadurunge aturan

Babagan pungkasan sing bakal kita demek dina iki yaiku prinsip " kedadeyan sadurunge ". Kaya sing wis dingerteni, ing Jawa, umume tugas kanggo ngalokasiake wektu lan sumber daya kanggo benang kanggo ngrampungake tugase ditindakake dening panjadwal benang. Sampeyan uga wis ndeleng luwih saka sapisan carane Utas sing dileksanakake ing urutan sembarang, lan paling asring iku mokal kanggo prédhiksi. Lan umume, sawise program "sequential" sing ditindakake sadurunge, multithreading katon kaya acak. Kaya sing wis dingerteni, kemajuan program multithreaded bisa dikontrol kanthi nggunakake macem-macem metode. Nanging saliyane iki, ing multithreading Jawa ana "pulau stabilitas" liyane - 4 aturan sing diarani " kedadeyan-sadurunge ". Secara harfiah saka basa Inggris iki dijarwakake minangka "kedadeyan sadurunge", utawa "kedadeyan sadurunge". Makna aturan kasebut cukup gampang dingerteni. Bayangake yen kita duwe rong benang - Alan B. Saben utas iki bisa nindakake operasi 1lan 2. Lan nalika ing saben aturan kita ngomong " A kedaden-sadurunge B ", iki tegese kabeh owah-owahan sing digawe dening thread Asadurunge operasi 1lan owah-owahan sing operasi iki entailed katon ing thread Bing wektu operasi dileksanakake 2lan sawise operasi ditindakake. Saben aturan iki mesthekake yen nalika nulis program multi-Utas, sawetara acara bakal kelakon sadurunge liyane 100% wektu, lan thread Bing wektu operasi 2bakal tansah weruh saka owah-owahan sing thread Аdigawe sak operasi. 1. Ayo padha ndeleng.

Aturan 1.

Ngeculake mutex kedadeyan sadurunge kedadeyan sadurunge thread liyane entuk monitor sing padha. Inggih, kabeh katon cetha ing kene. Yen mutex obyek utawa kelas dipikolehi dening siji Utas, contone, Utas А, Utas liyane (Utas B) ora bisa ndarbeni ing wektu sing padha. Sampeyan kudu ngenteni nganti mutex dirilis.

Aturan 2.

Cara Thread.start() sing kedadeyan sadurunge Thread.run() . Ora ana sing rumit. Sampeyan wis ngerti: supaya kode nang cara kanggo miwiti eksekusi run(), sampeyan kudu nelpon cara ing thread start(). Iku dheweke, lan dudu cara dhewe run()! Aturan iki njamin yen Thread.start()nilai kabeh variabel sing disetel sadurunge eksekusi bakal katon ing cara sing diwiwiti dieksekusi run().

Aturan 3.

Cara rampung run() sadurunge metode metu join(). Ayo bali menyang loro aliran kita - Аlan B. Kita nyebat metode kasebut join()kanthi cara supaya benang Bkudu ngenteni nganti rampung Asadurunge nindakake pakaryan. Iki tegese cara run()obyek A mesthi bakal mlaku nganti pungkasan. Lan kabeh owah-owahan ing data sing kedaden ing cara run()thread Abakal rampung katon ing thread Bnalika ngenteni rampung Alan wiwit digunakake dhewe.

Aturan 4.

Nulis menyang variabel molah malih kedadeyan sadurunge maca saka variabel sing padha. Kanthi nggunakake tembung kunci sing molah malih, kita mesthi bakal entuk nilai saiki. Malah ing cilik saka longlan double, masalah karo kang rembugan sadurungé. Kaya sing wis dingerteni, owah-owahan sing ditindakake ing sawetara utas ora mesthi katon ing utas liyane. Nanging, mesthi, asring banget ana kahanan nalika prilaku program kuwi ora cocog karo kita. Ayo kita nemtokake nilai kanggo variabel ing thread A:
int z;.

z= 555;
Yen utas kita Bbakal nyithak nilai variabel zmenyang konsol, bisa gampang dicithak 0 amarga ora ngerti babagan nilai sing diwenehake. Dadi, Aturan 4 njamin kita: yen sampeyan nyatakake variabel zminangka molah malih, owah-owahan ing nilai ing siji thread bakal tansah katon ing thread liyane. Yen kita nambah tembung molah malih menyang kode sadurungé ...
volatile int z;.

z= 555;
... kahanan kang stream Bbakal output 0 kanggo console tilar. Nulis kanggo variabel molah malih dumadi sadurunge maca saka wong-wong mau.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION