CodeGym /Java Blog /Random /Pag-synchronize ng thread. Ang naka-synchronize na operat...
John Squirrels
Antas
San Francisco

Pag-synchronize ng thread. Ang naka-synchronize na operator

Nai-publish sa grupo
Hi! Ngayon ay patuloy nating isasaalang-alang ang mga tampok ng multithreaded programming at pag-uusapan ang tungkol sa pag-synchronize ng thread. Pag-synchronize ng thread.  Ang naka-synchronize na operator - 1

Ano ang pag-synchronize sa Java?

Sa labas ng domain ng programming, ipinahihiwatig nito ang isang kaayusan na nagpapahintulot sa dalawang device o program na magtulungan. Halimbawa, maaaring i-synchronize ang isang smartphone at computer sa isang Google account, at maaaring i-sync ang isang website account sa mga social network account upang magamit mo ang mga ito para mag-sign in. Ang pag-synchronize ng thread ay may katulad na kahulugan: ito ay isang kaayusan kung saan nakikipag-ugnayan ang mga thread sa isa't isa. Sa mga nakaraang aralin, ang aming mga thread ay namuhay at nagtrabaho nang hiwalay sa isa't isa. Nagsagawa ng kalkulasyon ang isa, natulog ang pangalawa, at ang pangatlo ay nagpakita ng isang bagay sa console, ngunit hindi sila nakikipag-ugnayan. Sa totoong mga programa, bihira ang mga ganitong sitwasyon. Maaaring aktibong gumana ang maramihang mga thread at baguhin ang parehong set ng data. Lumilikha ito ng mga problema. Isipin ang maraming thread na nagsusulat ng text sa parehong lugar, halimbawa, sa isang text file o sa console. Sa kasong ito, ang file o console ay magiging isang nakabahaging mapagkukunan. Ang mga thread ay walang kamalayan sa pagkakaroon ng isa't isa, kaya't isinusulat lamang nila ang lahat ng kanilang makakaya sa oras na inilaan sa kanila ng thread scheduler. Sa isang kamakailang aralin, nakakita kami ng isang halimbawa kung saan ito humahantong. Alalahanin natin ito ngayon: Pag-synchronize ng thread.  Ang naka-synchronize na operator - 2Ang dahilan ay nakasalalay sa katotohanan na ang mga thread ay gumagana sa isang nakabahaging mapagkukunan (ang console) nang hindi nag-uugnay sa kanilang mga aksyon sa isa't isa. Kung ang thread scheduler ay naglalaan ng oras sa Thread-1, pagkatapos ay agad nitong isusulat ang lahat sa console. Kung ano ang mayroon o hindi pa nagawang isulat ng ibang mga thread ay hindi mahalaga. Ang resulta, tulad ng nakikita mo, ay nakapanlulumo. Kaya naman nagpakilala sila ng isang espesyal na konsepto, ang mutex (mutual exclusion) , sa multithreaded programming. Ang layunin ng isang mutexay upang magbigay ng isang mekanismo upang ang isang thread lamang ang may access sa isang bagay sa isang tiyak na oras. Kung nakuha ng Thread-1 ang mutex ng object A, hindi maa-access at mababago ng ibang mga thread ang object. Ang iba pang mga thread ay dapat maghintay hanggang ang object A's mutex ay ilabas. Narito ang isang halimbawa mula sa buhay: isipin na ikaw at ang 10 iba pang estranghero ay nakikilahok sa isang ehersisyo. Paghalili, kailangan mong ipahayag ang iyong mga ideya at pag-usapan ang isang bagay. Ngunit dahil sa unang pagkakataon ay nagkita-kita kayo, para hindi palagiang makagambala sa isa't isa at magalit, gumamit ka ng 'talking ball': ang taong may bola lang ang makakapagsalita. Sa ganitong paraan magkakaroon ka ng mabuti at mabungang talakayan. Mahalaga, ang bola ay isang mutex. Kung ang mutex ng isang bagay ay nasa kamay ng isang thread, ang ibang mga thread ay hindi maaaring gumana sa bagay.Objectclass, na nangangahulugan na ang bawat bagay sa Java ay may isa.

Paano gumagana ang naka-synchronize na operator

Kilalanin natin ang isang bagong keyword: naka-synchronize . Ito ay ginagamit upang markahan ang isang tiyak na bloke ng code. Kung ang isang bloke ng code ay minarkahan ng synchronizedkeyword, ang bloke na iyon ay maaari lamang isagawa ng isang thread sa bawat pagkakataon. Maaaring ipatupad ang pag-synchronize sa iba't ibang paraan. Halimbawa, sa pamamagitan ng pagdedeklara ng isang buong pamamaraan na i-synchronize:

public synchronized void doSomething() {

   // ...Method logic
}
O magsulat ng isang bloke ng code kung saan isinasagawa ang pag-synchronize gamit ang ilang bagay:

public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...Some logic available simultaneously to all threads

       synchronized (obj) {

           // Logic available to just one thread at a time
       }
   }
}
Simple lang ang kahulugan. Kung ang isang thread ay pumasok sa block ng code na minarkahan ng synchronizedkeyword, agad nitong kinukuha ang mutex ng object, at lahat ng iba pang mga thread na sumusubok na pumasok sa parehong bloke o paraan ay mapipilitang maghintay hanggang sa makumpleto ng nakaraang thread ang trabaho nito at ilabas ang monitor. Pag-synchronize ng thread.  Ang naka-synchronize na operator - 3Siya nga pala! Sa panahon ng kurso, nakakita ka na ng mga halimbawa ng synchronized, ngunit iba ang hitsura nila:

public void swap()
{
   synchronized (this)
   {
       // ...Method logic
   }
}
Ang paksa ay bago para sa iyo. At, siyempre, magkakaroon ng pagkalito sa syntax. Kaya, kabisaduhin ito kaagad upang hindi malito sa ibang pagkakataon sa iba't ibang paraan ng pagsulat nito. Iisa ang ibig sabihin ng dalawang paraan ng pagsulat nito:

public void swap() {

   synchronized (this)
   {
       // ...Method logic
   }
}


public synchronized void swap() {

   }
}
Sa unang kaso, gagawa ka kaagad ng naka-synchronize na bloke ng code sa pagpasok ng paraan. Ito ay naka-synchronize ng thisbagay, ibig sabihin, ang kasalukuyang bagay. At sa pangalawang halimbawa, inilapat mo ang synchronizedkeyword sa buong pamamaraan. Ginagawa nitong hindi kinakailangan na tahasang ipahiwatig ang bagay na ginagamit para sa pag-synchronize. Dahil ang buong pamamaraan ay minarkahan ng keyword, ang pamamaraan ay awtomatikong masi-synchronize para sa lahat ng mga pagkakataon ng klase. Hindi kami sumisid sa isang talakayan tungkol sa kung aling paraan ang mas mahusay. Sa ngayon, piliin ang alinmang paraan na gusto mo :) Ang pangunahing bagay ay tandaan: maaari mong ideklara ang isang pamamaraan na naka-synchronize lamang kapag ang lahat ng lohika nito ay naisakatuparan ng isang thread sa isang pagkakataon. Halimbawa, magiging isang pagkakamali na gawing naka doSomething()-synchronize ang sumusunod na paraan:

public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...Some logic available simultaneously to all threads

       synchronized (obj) {

           // Logic available to just one thread at a time
       }
   }
}
Tulad ng nakikita mo, ang bahagi ng pamamaraan ay naglalaman ng lohika na hindi nangangailangan ng pag-synchronize. Ang code na iyon ay maaaring patakbuhin ng maramihang mga thread nang sabay-sabay, at ang lahat ng mga kritikal na lugar ay nakahiwalay sa isang hiwalay na synchronizedbloke. At isa pa. Suriin nating mabuti ang ating halimbawa mula sa aralin na may pagpapalit ng pangalan:

public void swap()
{
   synchronized (this)
   {
       // ...Method logic
   }
}
Tandaan: ginagawa ang pag-synchronize gamit angthis. Iyon ay, gamit ang isang tiyakMyClassna bagay. Ipagpalagay na mayroon kaming 2 mga thread (Thread-1atThread-2) at isangMyClass myClassbagay lamang. Sa kasong ito, kungThread-1tatawagin angmyClass.swap()pamamaraan, magiging abala ang mutex ng bagay, at kapag sinusubukang tawagan angmyClass.swap()pamamaraanThread-2ay mag-hang habang naghihintay na mailabas ang mutex. Kung magkakaroon tayo ng 2 thread at 2MyClassobject (myClass1atmyClass2), ang ating mga thread ay madaling sabay na maisakatuparan ang mga naka-synchronize na pamamaraan sa iba't ibang bagay. Ang unang thread ay nagpapatupad nito:

myClass1.swap();
Ang pangalawa ay nagsasagawa nito:

myClass2.swap();
Sa kasong ito, ang synchronizedkeyword sa loob ng swap()pamamaraan ay hindi makakaapekto sa pagpapatakbo ng programa, dahil ang pag-synchronize ay isinasagawa gamit ang isang partikular na bagay. At sa huling kaso, mayroon kaming 2 bagay. Kaya, ang mga thread ay hindi gumagawa ng mga problema para sa isa't isa. Pagkatapos ng lahat, ang dalawang bagay ay may 2 magkaibang mutex, at ang pagkuha ng isa ay hiwalay sa pagkuha ng isa .

Mga espesyal na tampok ng pag-synchronize sa mga static na pamamaraan

Ngunit paano kung kailangan mong i-synchronize ang isang static na paraan ?

class MyClass {
   private static String name1 = "Ally";
   private static String name2 = "Lena";

   public static synchronized void swap() {
       String s = name1;
       name1 = name2;
       name2 = s;
   }

}
Hindi malinaw kung anong papel ang gagampanan ng mutex dito. Pagkatapos ng lahat, natukoy na namin na ang bawat bagay ay may mutex. Ngunit ang problema ay hindi namin kailangan ng mga bagay upang tawagan ang MyClass.swap()pamamaraan: ang pamamaraan ay static! Tapos anung susunod? :/ Wala naman talagang problema dito. Ang mga tagalikha ng Java ay nag-ingat sa lahat :) Kung ang isang pamamaraan na naglalaman ng kritikal na kasabay na lohika ay static, ang pag-synchronize ay isinasagawa sa antas ng klase. Para sa higit na kalinawan, maaari naming muling isulat ang code sa itaas tulad ng sumusunod:

class MyClass {
   private static String name1 = "Ally";
   private static String name2 = "Lena";

   public static void swap() {

       synchronized (MyClass.class) {
           String s = name1;
           name1 = name2;
           name2 = s;
       }
   }

}
Sa prinsipyo, maaari mong naisip ito sa iyong sarili: Dahil walang mga bagay, ang mekanismo ng pag-synchronize ay dapat na kahit papaano ay inihurnong sa klase mismo. At ganoon talaga ito: maaari tayong gumamit ng mga klase para i-synchronize.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION