CodeGym /Java Blog /Random /Multithreading: Ano ang ginagawa ng mga pamamaraan ng Thr...
John Squirrels
Antas
San Francisco

Multithreading: Ano ang ginagawa ng mga pamamaraan ng Thread class

Nai-publish sa grupo
Hi! Ngayon ay patuloy nating pag-uusapan ang tungkol sa multithreading. Suriin natin ang klase ng Thread at kung ano ang ginagawa ng ilan sa mga pamamaraan nito. Noong nag-aral kami ng mga pamamaraan ng klase dati, kadalasan ay sinusulat lang namin ito: <pangalan ng pamamaraan> -> <kung ano ang ginagawa ng pamamaraan>. Multithreading: Ano ang ginagawa ng mga pamamaraan ng Thread class - 1Hindi ito gagana sa Threadmga pamamaraan ni :) Mayroon silang mas kumplikadong lohika na hindi mo malalaman nang walang ilang mga halimbawa.

Ang Thread.start() method

Magsimula tayo sa pamamagitan ng pag-uulit sa ating sarili. Tulad ng malamang na naaalala mo, maaari kang lumikha ng isang thread sa pamamagitan ng paggawa ng iyong klase na magmana ng Threadklase at i-override ang run()pamamaraan. Ngunit hindi ito magsisimula mismo, siyempre. Upang gawin ito, tinatawag namin start()ang pamamaraan ng aming object. Multithreading: Ano ang ginagawa ng mga pamamaraan ng klase ng Thread - 2Alalahanin natin ang halimbawa mula sa nakaraang aralin:

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Thread executed: " + getName());
   }
}


public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Tandaan: Upang magsimula ng isang thread, dapat mong tawagan ang espesyalstart()na paraan sa halip na angrun()paraan! Ito ay isang madaling pagkakamali, lalo na noong una kang nagsimulang mag-aral ng multithreading. Sa aming halimbawa, kung tatawagin mo angrun()pamamaraan nang 10 beses sa halip nastart(), makukuha mo ito:

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Tingnan ang mga resulta ng aming programa: Thread executed: Thread-0 Thread executed: Thread-1 Thread executed: Thread-2 Thread executed: Thread-3 Thread executed: Thread-4 Thread executed: Thread-5 Thread executed: Thread-6 Naisagawa ang Thread: Naisagawa ang Thread-7 Naisagawa ang Thread: Naisagawa ang Thread-8 Naisagawa ang Thread: Thread-9 Tingnan ang pagkakasunud-sunod ng output: Ang lahat ay nangyayari sa perpektong pagkakasunud-sunod. Kakaiba, ha? Hindi kami sanay dito, dahil alam na namin na ang pagkakasunud-sunod ng pagsisimula at pag-execute ng mga thread ay tinutukoy ng isang superyor na talino sa loob ng aming operating system: ang thread scheduler. Baka sinuwerte lang tayo? Siyempre, hindi ito tungkol sa swerte. Maaari mong i-verify ito sa pamamagitan ng pagpapatakbo ng programa nang ilang beses pa. Ang isyu ay ang tawag sarun()direktang walang kinalaman ang pamamaraan sa multithreading. Sa kasong ito, ang programa ay isasagawa sa pangunahing thread, ang parehong thread na nagpapatupad ng main()pamamaraan. Ito ay sunud-sunod na nagpi-print ng 10 linya sa console at iyon na. 10 thread ang hindi pa nasisimulan. Kaya, tandaan ito sa hinaharap at patuloy na suriin ang iyong sarili. Kung gusto mong run()tawagan ang pamamaraan, tumawag sa start(). Tayo ay pumunta sa karagdagang.

Ang Thread.sleep() na pamamaraan

Upang masuspinde ang pagpapatupad ng kasalukuyang thread nang ilang sandali, ginagamit namin ang sleep()pamamaraan. Multithreading: Ano ang ginagawa ng mga pamamaraan ng Thread class - 3Ang sleep()pamamaraan ay tumatagal ng isang bilang ng mga millisecond bilang isang argumento, na nagpapahiwatig ng dami ng oras upang ilagay ang thread sa pagtulog.

public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - How long did I sleep? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " seconds");

   }
}
Output ng console: - Gaano katagal ako nakatulog? - 3 segundo Tandaan: ang sleep()pamamaraan ay static: pinatutulog nito ang kasalukuyang thread. Ibig sabihin, ang kasalukuyang pinapatay. Narito ang isa pang mahalagang punto: ang isang natutulog na thread ay maaaring maputol. Sa kasong ito, ang programa ay nagtatapon ng isang InterruptedException. Isasaalang-alang namin ang isang halimbawa sa ibaba. By the way, ano ang mangyayari pagkatapos magising ang thread? Magpapatuloy ba itong isakatuparan mula mismo sa kung saan ito tumigil? Hindi. Matapos magising ang isang thread, ibig sabihin, lumipas ang oras bilang argumento Thread.sleep(), lumilipat ito sa runnableestado. Ngunit, hindi ito nangangahulugan na ang thread scheduler ang tatakbo nito. Maaaring mas gusto nito ang ilang iba pang thread na hindi natutulog at payagan ang aming bagong gising na thread na ipagpatuloy ang trabaho nito sa ibang pagkakataon. Siguraduhing tandaan ito: ang paggising ay hindi nangangahulugan ng patuloy na trabaho kaagad!

Ang Thread.join() na pamamaraan

Multithreading: Ano ang ginagawa ng mga pamamaraan ng Thread class - 4Ang join()pamamaraan ay sinuspinde ang pagpapatupad ng kasalukuyang thread hanggang sa matapos ang isa pang thread. Kung mayroon kaming 2 thread, t1at t2, at sumulat kami

t1.join()
pagkatapos t2ay hindi magsisimula hanggang sa t1matapos ang gawain nito. join()Maaaring gamitin ang pamamaraan upang magarantiya ang pagkakasunud-sunod ng pagpapatupad ng mga thread. Isaalang-alang natin kung paano join()gumagana ang pamamaraan sa sumusunod na halimbawa:

public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Thread started: " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Thread " + getName() + " is finished.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /* The second thread (t2) will start running only after the first thread (t1)
       is finished (or an exception is thrown) */
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       // The main thread will continue running only after t1 and t2 have finished
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("All threads have finished. The program is finished.");

   }
}
Gumawa kami ng isang simpleng ThreadExampleklase. Ang gawain nito ay magpakita ng mensahe na nagsimula na ang thread, matulog ng 5 segundo, at pagkatapos ay iulat sa wakas na kumpleto na ang gawain. Madali lang. Ang pangunahing lohika ay nasa Mainklase. Tingnan ang mga komento: ginagamit namin ang join()paraan upang matagumpay na pamahalaan ang pagkakasunud-sunod ng pagpapatupad ng mga thread. Kung naaalala mo kung paano namin sinimulan ang paksang ito, ang execution order ay pinangangasiwaan ng thread scheduler. Nagpapatakbo ito ng mga thread sa sarili nitong paghuhusga: sa bawat oras sa ibang paraan. Dito ginagamit namin ang paraan upang magarantiya na ang t1thread ay unang sisimulan at isasagawa muna, pagkatapos ay angt2thread, at pagkatapos lamang nito ay magpapatuloy ang pangunahing thread ng programa. Moving on. Sa mga tunay na programa, madalas kang makakahanap ng mga sitwasyon kung kailan kailangan mong matakpan ang pagpapatupad ng isang thread. Halimbawa, tumatakbo ang aming thread, ngunit naghihintay ito ng isang partikular na kaganapan o kundisyon. Kung nangyari ito, pagkatapos ay hihinto ang thread. Malamang na magkaroon ng kahulugan kung mayroong isang uri ng stop()pamamaraan. Ngunit ito ay hindi gaanong simple. Noong unang panahon, talagang may Thread.stop()pamamaraan ang Java at pinahintulutan ang isang thread na magambala. Ngunit kalaunan ay inalis ito sa library ng Java. Mahahanap mo ito sa dokumentasyon ng Oracle at makita na minarkahan ito bilang hindi na ginagamit. Bakit? Dahil pinahinto lang nito ang thread na walang ginagawa. Halimbawa, ang thread ay maaaring gumagana sa data at nagbabago ng isang bagay. Pagkatapos ay sa gitna ng trabaho nito ay bigla at walang galang na pinutol ng stop()pamamaraan. Nang walang wastong pagsasara, ni ang paglabas ng mga mapagkukunan, kahit na ang paghawak ng error — wala nito. Upang palakihin nang bahagya, stop()sinira lamang ng pamamaraan ang lahat sa paraan nito. Parang hinila ang kurdon ng kuryente mula sa saksakan para patayin ang computer. Oo, maaari mong makuha ang ninanais na resulta. Ngunit alam ng lahat na pagkatapos ng ilang linggo ang computer ay hindi magpapasalamat sa iyo sa pagtrato nito sa ganoong paraan. Iyon ang dahilan kung bakit ang lohika para sa pag-abala sa mga thread ay nagbago sa Java at ngayon ay gumagamit ng isang espesyal interrupt()na paraan.

Ang Thread.interrupt() method

Ano ang mangyayari kung ang interrupt()pamamaraan ay tinatawag sa isang thread? Mayroong 2 posibilidad:
  1. Kung ang bagay ay nasa estado ng paghihintay, halimbawa, dahil sa joino sleepmga pamamaraan, ang paghihintay ay maaantala at ang programa ay magtapon ng isang InterruptedException.
  2. Kung ang thread ay nasa isang gumaganang estado, ang boolean interruptedflag ay itatakda sa object.
Ngunit kailangan nating suriin ang halaga ng watawat na ito sa bagay at tama na kumpletuhin ang gawain sa ating sarili! Kaya naman Threadmay boolean isInterrupted()pamamaraan ang klase. Bumalik tayo sa halimbawa ng orasan na nasa isang aralin sa pangunahing kurso. Para sa kaginhawahan, pinasimple namin ito nang bahagya:

public class Clock extends Thread {

   public static void main(String[] args) throws InterruptedException {
       Clock clock = new Clock();
       clock.start();

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("The thread was interrupted");
               break;
           }
           System.out.println("Tick");
       }
   }
}
Sa kasong ito, ang orasan ay nagsisimula at nagsisimulang mag-tick bawat segundo. Sa ika-10 segundo, ginagambala namin ang thread ng orasan. Tulad ng alam mo na, kung ang thread na sinusubukan naming matakpan ay nasa isa sa mga naghihintay na estado, ang resulta ay isang InterruptedException. Isa itong checked exception, para madali natin itong mahuli at maisakatuparan ang ating logic para matapos ang program. At iyon lang ang ginawa namin. Narito ang aming resulta: Tick Tick Tick Tcik Tick Tick Tick Tick Tick Ang thread ay nagambala Ito ay nagtatapos sa aming pagpapakilala sa mga Threadpinakamahalagang pamamaraan ng klase. Good luck!
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION