CodeGym /Java blog /Tilfældig /Multithreading: Hvad gør metoderne i Thread-klassen
John Squirrels
Niveau
San Francisco

Multithreading: Hvad gør metoderne i Thread-klassen

Udgivet i gruppen
Hej! I dag vil vi fortsætte med at tale om multithreading. Lad os undersøge Thread-klassen og hvad nogle få af dens metoder gør. Når vi tidligere studerede klassemetoder, skrev vi normalt bare dette: <metodenavn> -> <hvad metoden gør>. Multithreading: Hvad gør metoderne i Thread-klassen - 1Dette vil ikke fungere med Thread's metoder :) De har mere kompleks logik, som du ikke vil være i stand til at finde ud af uden et par eksempler.

Thread.start() metoden

Lad os starte med at gentage os selv. Som du sikkert husker, kan du oprette en tråd ved at få din klasse til at arve klassen Threadog tilsidesætte run()metoden. Men det starter selvfølgelig ikke af sig selv. For at gøre dette kalder vi vores objekts start()metode. Multithreading: Hvad gør metoderne i Thread-klassen - 2Lad os huske eksemplet fra den forrige lektion:

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();
       }
   }
}
Bemærk: For at starte en tråd skal du kalde den speciellestart()metode frem forrun()metoden! Dette er en let fejl at lave, især når du først begynder at studere multithreading. I vores eksempel, hvis du kalderrun()metoden 10 gange i stedet forstart(), vil du få dette:

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Se på resultaterne af vores program: Tråd udført: Tråd-0 Tråd udført: Tråd-1 Tråd udført: Tråd-2 Tråd udført: Tråd-3 Tråd udført: Tråd-4 Tråd udført: Tråd-5 Tråd udført: Tråd-6 Tråd udført: Tråd-7 Tråd udført: Tråd-8 Tråd udført: Tråd-9 Se på rækkefølgen af ​​output: Alt sker i perfekt rækkefølge. Underligt, hva'? Vi er ikke vant til dette, fordi vi allerede ved, at rækkefølgen, hvori tråde startes og udføres, bestemmes af en overlegen intellekt inde i vores operativsystem: trådplanlæggeren. Måske var vi bare heldige? Det handler selvfølgelig ikke om held. Du kan bekræfte dette ved at køre programmet et par gange mere. Problemet er, at kalderun()metode har direkte intet at gøre med multithreading. I dette tilfælde vil programmet blive udført på hovedtråden, den samme tråd som udfører metoden main(). Den udskriver simpelthen 10 linjer successivt på konsollen, og det er det. 10 tråde er ikke startet. Så husk dette i fremtiden og tjek dig selv konstant. Hvis du ønsker, at run()metoden skal kaldes, ring start(). Lad os gå videre.

Thread.sleep() metoden

For at suspendere udførelsen af ​​den aktuelle tråd i et stykke tid, bruger vi sleep()metoden. Multithreading: Hvad gør metoderne i Thread-klassen - 3Metoden sleep()tager et antal millisekunder som argument, som angiver, hvor lang tid det tager at sætte tråden i dvale.

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");

   }
}
Konsoludgang: - Hvor længe sov jeg? - 3 sekunder Bemærk: metoden sleep()er statisk: den holder den aktuelle tråd i dvale. Det vil sige den, der i øjeblikket bliver henrettet. Her er et andet vigtigt punkt: en sovende tråd kan blive afbrudt. I dette tilfælde kaster programmet en InterruptedException. Vi vil overveje et eksempel nedenfor. Hvad sker der i øvrigt efter tråden vågner op? Vil det fortsætte med at blive udført lige fra hvor det slap? Nej. Efter at en tråd vågner op, dvs. den tid, der gik som et argument til, Thread.sleep()er gået, går den over til at kunne køresstat. Men dette betyder ikke, at trådplanlæggeren kører det. Det kan meget vel give fortrinsret til en anden ikke-sovende tråd og lade vores nyvågne tråd fortsætte sit arbejde lidt senere. Sørg for at huske dette: At vågne betyder ikke at fortsætte arbejdet med det samme!

Thread.join() metoden

Multithreading: Hvad gør metoderne i Thread-klassen - 4Metoden join()suspenderer udførelsen af ​​den aktuelle tråd, indtil en anden tråd afsluttes. Hvis vi har 2 tråde, t1og t2, og vi skriver

t1.join()
t2starter den ikke før t1den er færdig. Metoden join()kan bruges til at garantere udførelsesrækkefølgen af ​​tråde. Lad os overveje, hvordan join()metoden fungerer i følgende eksempel:

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.");

   }
}
Vi lavede en simpel ThreadExampleklasse. Dens opgave er at vise en besked om, at tråden er startet, falde i søvn i 5 sekunder og så endelig rapportere, at arbejdet er afsluttet. Et stykke kage. Hovedlogikken er i Mainklassen. Se på kommentarerne: vi bruger join()metoden til at administrere trådenes eksekveringsrækkefølge. Hvis du husker, hvordan vi startede dette emne, håndteres udførelsesrækkefølgen af ​​trådplanlæggeren. Det kører tråde efter eget skøn: hver gang på en anden måde. Her bruger vi metoden til at garantere, at t1tråden først startes og køres først, dereftert2tråd, og først derefter fortsætter programmets hovedtråd. Komme videre. I rigtige programmer vil du ofte finde situationer, hvor du bliver nødt til at afbryde udførelsen af ​​en tråd. For eksempel kører vores tråd, men den venter på en bestemt begivenhed eller tilstand. Hvis det sker, stopper tråden. Det ville nok give mening, hvis der var en form for stop()metode. Men det er ikke så enkelt. Engang havde Java faktisk en Thread.stop()metode og tillod en tråd at blive afbrudt. Men det blev senere fjernet fra Java-biblioteket. Du kan finde den i Oracle-dokumentationen og se, at den er markeret som forældet. Hvorfor? For den stoppede bare tråden uden at gøre andet. For eksempel kan tråden arbejde med data og ændre noget. Så midt i arbejdet blev det brat og uhøjtideligt afskåret af stop()metoden. Uden en ordentlig nedlukning eller frigivelse af ressourcer, ikke engang fejlhåndtering - der var intet af dette. For at overdrive lidt, stop()ødelagde metoden simpelthen alt på sin måde. Det var som at trække netledningen ud af stikkontakten for at slukke for computeren. Ja, du kan få det ønskede resultat. Men alle ved, at efter et par uger vil computeren ikke takke dig for at behandle den på den måde. Det er derfor, logikken for at afbryde tråde ændrede sig i Java og bruger nu en speciel interrupt()metode.

Thread.interrupt() metoden

Hvad sker der, hvis interrupt()metoden kaldes på en tråd? Der er 2 muligheder:
  1. Hvis objektet var i ventetilstand, for eksempel på grund af joineller sleepmetoderne, vil ventetiden blive afbrudt, og programmet vil kaste en InterruptedException.
  2. Hvis tråden var i en fungerende tilstand, interruptedvil det booleske flag blive sat på objektet.
Men vi er nødt til at kontrollere værdien af ​​dette flag på objektet og udføre arbejdet korrekt på egen hånd! Det er derfor, Threadklassen har boolean isInterrupted()metoden. Lad os vende tilbage til ureksemplet, der var i en lektion i grundforløbet. For nemheds skyld har vi forenklet det lidt:

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");
       }
   }
}
I dette tilfælde startes uret og begynder at tikke hvert sekund. I 10. sekund afbryder vi urets tråd. Som du allerede ved, hvis tråden, som vi forsøger at afbryde, er i en af ​​ventetilstandene, er resultatet en InterruptedException. Dette er en kontrolleret undtagelse, så vi kan nemt fange den og udføre vores logik for at afslutte programmet. Og det er lige, hvad vi gjorde. Her er vores resultat: Tick Tick Tik Tik Tik Tik Tik Tik Tik Tik Tik Tråden blev afbrudt Dette afslutter vores introduktion til Threadklassens vigtigste metoder. Held og lykke!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION