CodeGym/Java-blogg/Tilfeldig/Multithreading: Hva metodene i Thread-klassen gjør
John Squirrels
Nivå
San Francisco

Multithreading: Hva metodene i Thread-klassen gjør

Publisert i gruppen
Hei! I dag skal vi fortsette å snakke om multithreading. La oss undersøke Thread-klassen og hva noen av metodene gjør. Når vi studerte klassemetoder tidligere, skrev vi vanligvis bare dette: <metodenavn> -> <hva metoden gjør>. Multithreading: Hva metodene i Thread-klassen gjør - 1Dette vil ikke fungere med Thread's metoder :) De har mer kompleks logikk som du ikke vil kunne finne ut av uten noen få eksempler.

Thread.start()-metoden

La oss starte med å gjenta oss selv. Som du sikkert husker, kan du opprette en tråd ved å få klassen til å arve klassen Threadog overstyre run()metoden. Men det starter ikke av seg selv, selvfølgelig. For å gjøre dette kaller vi objektets start()metode. Multithreading: Hva metodene i Thread-klassen gjør - 2La oss huske eksemplet fra forrige leksjon:
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();
       }
   }
}
Merk: For å starte en tråd må du kalle spesialmetodenstart()i stedet forrun()metoden! Dette er en enkel feil å gjøre, spesielt når du først begynner å studere multithreading. I vårt eksempel, hvis du kallerrun()metoden 10 ganger 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å resultatene av programmet vårt: Tråd utført: Tråd-0 Tråd utført: Tråd-1 Tråd utført: Tråd-2 Tråd utført: Tråd-3 Tråd utført: Tråd-4 Tråd utført: Tråd-5 Tråd utført: Tråd-6 Tråd utført: Tråd-7 Tråd utført: Tråd-8 Tråd utført: Tråd-9 Se på rekkefølgen på utdataene: Alt skjer i perfekt rekkefølge. Rart, ikke sant? Vi er ikke vant til dette, fordi vi allerede vet at rekkefølgen som tråder startes og kjøres i, bestemmes av et overordnet intellekt inne i operativsystemet vårt: trådplanleggeren. Kanskje vi bare var heldige? Dette handler selvfølgelig ikke om flaks. Du kan bekrefte dette ved å kjøre programmet et par ganger til. Problemet er at samtalenrun()metoden har direkte ingenting med multithreading å gjøre. I dette tilfellet vil programmet kjøres på hovedtråden, den samme tråden som kjører metoden main(). Den skriver ganske enkelt ut 10 linjer suksessivt på konsollen, og det er det. 10 tråder er ikke startet. Så husk dette i fremtiden og sjekk deg selv hele tiden. Hvis du vil at run()metoden skal kalles, ring start(). La oss gå videre.

Thread.sleep()-metoden

For å suspendere kjøringen av den gjeldende tråden en stund bruker vi metoden sleep(). Multithreading: Hva metodene i Thread-klassen gjør - 3Metoden sleep()tar et antall millisekunder som argument, som angir hvor lang tid det tar å sette 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");

   }
}
Konsollutgang: - Hvor lenge sov jeg? - 3 sekunder Merk: metoden sleep()er statisk: den sover gjeldende tråd. Det vil si den som nå henrettes. Her er et annet viktig poeng: en sovende tråd kan bli avbrutt. I dette tilfellet kaster programmet en InterruptedException. Vi vil vurdere et eksempel nedenfor. Hva skjer forresten etter at tråden våkner? Vil den fortsette å bli utført akkurat der den slapp? Nei. Etter at en tråd våkner, dvs. tiden som gikk som et argument til Thread.sleep()har gått, går den over til kjørbarstat. Men dette betyr ikke at trådplanleggeren vil kjøre den. Det kan muligens gi preferanse til en annen ikke-sovende tråd og la vår nyvåkne tråd fortsette arbeidet litt senere. Husk å huske dette: Å våkne betyr ikke å fortsette arbeidet umiddelbart!

Thread.join()-metoden

Multithreading: Hva metodene i Thread-klassen gjør - 4Metoden join()suspenderer kjøringen av gjeldende tråd til en annen tråd er ferdig. Hvis vi har 2 tråder, t1og t2, og vi skriver
t1.join()
t2starter ikke før arbeidet t1er ferdig. Metoden join()kan brukes til å garantere utførelsesrekkefølgen til tråder. La oss vurdere 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 laget en enkel ThreadExampleklasse. Dens oppgave er å vise en melding om at tråden har startet, sovne i 5 sekunder, og så til slutt rapportere at arbeidet er fullført. Lett som bare det. Hovedlogikken ligger i Mainklassen. Se på kommentarene: vi bruker join()metoden for å administrere trådenes utførelsesrekkefølge. Hvis du husker hvordan vi startet dette emnet, håndteres utførelsesrekkefølgen av trådplanleggeren. Den kjører tråder etter eget skjønn: hver gang på en annen måte. Her bruker vi metoden for å garantere at t1tråden først startes og kjøres først, derettert2tråd, og først etter det vil programmets hovedtråd fortsette. Går videre. I ekte programmer vil du ofte finne situasjoner når du må avbryte kjøringen av en tråd. For eksempel kjører tråden vår, men den venter på en bestemt hendelse eller tilstand. Hvis det skjer, stopper tråden. Det ville nok vært fornuftig om det fantes en slags stop()metode. Men det er ikke så enkelt. En gang i tiden hadde Java faktisk en Thread.stop()metode og tillot at en tråd ble avbrutt. Men det ble senere fjernet fra Java-biblioteket. Du kan finne den i Oracle-dokumentasjonen og se at den er merket som utdatert. Hvorfor? Fordi det bare stoppet tråden uten å gjøre noe annet. For eksempel kan tråden jobbe med data og endre noe. Så midt i arbeidet ble det brått og uhøytidelig avskåret av metoden stop(). Uten en skikkelig nedleggelse, heller ikke frigjøring av ressurser, ikke engang feilhåndtering - det var ingenting av dette. For å overdrive litt, stop()ødela metoden rett og slett alt på sin måte. Det var som å trekke strømledningen ut av stikkontakten for å slå av datamaskinen. Ja, du kan få ønsket resultat. Men alle vet at etter et par uker vil datamaskinen ikke takke deg for at du behandler den på den måten. Det er derfor logikken for å avbryte tråder endret seg i Java og bruker nå en spesiell interrupt()metode.

Thread.interrupt()-metoden

Hva skjer hvis interrupt()metoden kalles på en tråd? Det er 2 muligheter:
  1. Hvis objektet var i ventetilstand, for eksempel på grunn av eller- joinmetodene sleep, vil ventetiden bli avbrutt og programmet vil kaste en InterruptedException.
  2. Hvis tråden var i en fungerende tilstand, interruptedvil det boolske flagget settes på objektet.
Men vi må sjekke verdien av dette flagget på objektet og fullføre arbeidet på egen hånd! Det er derfor Threadklassen har boolean isInterrupted()metoden. La oss gå tilbake til klokkeeksemplet som var i en leksjon i grunnkurset. For enkelhets skyld har vi forenklet det litt:
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 tilfellet startes klokken og begynner å tikke hvert sekund. I det 10. sekundet avbryter vi klokkens tråd. Som du allerede vet, hvis tråden vi prøver å avbryte er i en av ventetilstandene, er resultatet en InterruptedException. Dette er et sjekket unntak, så vi kan enkelt fange det og utføre logikken vår for å fullføre programmet. Og det var akkurat det vi gjorde. Her er resultatet vårt: Tick Tick Tick Tcik Tikk Tikk Tikk Tikk Tikk Tråden ble avbrutt Dette avslutter vår introduksjon til Threadklassens viktigste metoder. Lykke til!
Kommentarer
  • Populær
  • Ny
  • Gammel
Du må være pålogget for å legge igjen en kommentar
Denne siden har ingen kommentarer ennå