CodeGym /Java Blog /Willekeurig /Multithreading: wat de methoden van de klasse Thread doen...
John Squirrels
Niveau 41
San Francisco

Multithreading: wat de methoden van de klasse Thread doen

Gepubliceerd in de groep Willekeurig
Hoi! Vandaag zullen we het verder hebben over multithreading. Laten we eens kijken naar de klasse Thread en wat enkele van zijn methoden doen. Toen we eerder klassenmethoden bestudeerden, schreven we meestal gewoon dit: <methodenaam> -> <wat de methode doet>. Multithreading: wat de methoden van de klasse Thread doen - 1Dit werkt niet met Threadde methoden van 's :) Ze hebben een complexere logica die je zonder een paar voorbeelden niet zult kunnen achterhalen.

De methode Thread.start()

Laten we beginnen met onszelf te herhalen. Zoals je je waarschijnlijk herinnert, kun je een thread maken door je klasse de Threadklasse te laten erven en de run()methode te overschrijven. Maar hij start natuurlijk niet vanzelf. Om dit te doen, noemen we de methode van ons object start(). Multithreading: wat de methoden van de klasse Thread doen - 2Laten we het voorbeeld uit de vorige les terughalen:

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();
       }
   }
}
Opmerking: om een ​​thread te starten, moet u de speciale methode aanroepenstart()in plaats van derun()methode! Dit is een makkelijke fout om te maken, vooral wanneer je voor het eerst multithreading gaat bestuderen. Als u in ons voorbeeld derun()methode 10 keer aanroept in plaats vanstart(), krijgt u dit:

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Kijk naar de resultaten van ons programma: Thread uitgevoerd: Thread-0 Thread uitgevoerd: Thread-1 Thread uitgevoerd: Thread-2 Thread uitgevoerd: Thread-3 Thread uitgevoerd: Thread-4 Thread uitgevoerd: Thread-5 Thread uitgevoerd: Thread-6 Thread uitgevoerd: Thread-7 Thread uitgevoerd: Thread-8 Thread uitgevoerd: Thread-9 Kijk naar de volgorde van de output: Alles gebeurt in perfecte volgorde. Raar, hè? We zijn dit niet gewend, omdat we al weten dat de volgorde waarin threads worden gestart en uitgevoerd, wordt bepaald door een superieur intellect binnen ons besturingssysteem: de threadplanner. Misschien hebben we gewoon geluk gehad? Het gaat hier natuurlijk niet om geluk. U kunt dit controleren door het programma nog een paar keer uit te voeren. Het probleem is dat bel derun()methode heeft niets te maken met multithreading. In dit geval wordt het programma uitgevoerd op de hoofdthread, dezelfde thread die de main()methode uitvoert. Het print gewoon achtereenvolgens 10 regels op de console en dat is alles. 10 threads zijn niet gestart. Onthoud dit dus in de toekomst en controleer jezelf constant. Als u wilt dat de run()methode wordt aangeroepen, roept u aan start(). Laten we verder gaan.

De methode Thread.sleep().

Om de uitvoering van de huidige thread een tijdje op te schorten, gebruiken we de sleep()methode. Multithreading: wat de methoden van de klasse Thread doen - 3De sleep()methode neemt een aantal milliseconden als argument, wat aangeeft hoeveel tijd het kost om de thread in slaapstand te brengen.

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

   }
}
Console-uitvoer: - Hoe lang heb ik geslapen? - 3 seconden Let op: de sleep()methode is statisch: het slaapt de huidige thread. Dat wil zeggen, degene die momenteel wordt uitgevoerd. Hier is nog een belangrijk punt: een slapende draad kan worden onderbroken. In dit geval gooit het programma een InterruptedException. We zullen hieronder een voorbeeld bekijken. Trouwens, wat gebeurt er nadat de thread wakker wordt? Zal het verder worden uitgevoerd vanaf waar het was gebleven? Nee. Nadat een thread ontwaakt, dwz de tijd die is verstreken als argument voor Thread.sleep()is verstreken, gaat deze over in uitvoerbaarstaat. Maar dit betekent niet dat de threadplanner het zal uitvoeren. Het is heel goed mogelijk dat het de voorkeur geeft aan een andere niet-slapende draad en onze pas ontwaakte draad even later zijn werk laat voortzetten. Onthoud dit zeker: wakker worden betekent niet meteen verder werken!

De methode Thread.join().

Multithreading: wat de methoden van de klasse Thread doen - 4De join()methode onderbreekt de uitvoering van de huidige thread totdat een andere thread klaar is. Als we 2 threads hebben, t1en t2, en we schrijven

t1.join()
t2start dan pas als t1het klaar is met zijn werk. De join()methode kan worden gebruikt om de uitvoeringsvolgorde van threads te garanderen. Laten we eens kijken hoe de join()methode werkt in het volgende voorbeeld:

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

   }
}
We hebben een eenvoudige ThreadExampleklas gemaakt. Het is zijn taak om een ​​bericht weer te geven dat de thread is gestart, 5 seconden in slaap te vallen en vervolgens te melden dat het werk is voltooid. Fluitje van een cent. De belangrijkste logica zit in de Mainklas. Kijk naar de opmerkingen: we gebruiken de join()methode om de uitvoeringsvolgorde van de threads met succes te beheren. Als je je herinnert hoe we dit onderwerp begonnen, wordt de uitvoeringsvolgorde afgehandeld door de threadplanner. Het voert threads naar eigen goeddunken uit: elke keer op een andere manier. Hier gebruiken we de methode om te garanderen dat de t1thread eerst wordt gestart en uitgevoerd, daarna det2thread, en pas daarna gaat de hoofdthread van het programma verder. Verder gaan. In echte programma's kom je vaak situaties tegen waarin je de uitvoering van een thread moet onderbreken. Onze thread is bijvoorbeeld actief, maar wacht op een bepaalde gebeurtenis of voorwaarde. Als het gebeurt, stopt de draad. Het zou waarschijnlijk logisch zijn als er een methode was stop(). Maar zo eenvoudig is het niet. Java had ooit een Thread.stop()methode en stond toe dat een thread werd onderbroken. Maar het werd later verwijderd uit de Java-bibliotheek. U kunt het vinden in de Oracle-documentatie en zien dat het is gemarkeerd als verouderd. Waarom? Omdat het gewoon de draad stopte zonder iets anders te doen. De thread werkt bijvoorbeeld met gegevens en verandert iets. Toen werd het midden in zijn werk abrupt en zonder pardon afgebroken door de stop()methode. Zonder een goede afsluiting, noch het vrijgeven van bronnen, zelfs geen foutafhandeling - was er niets van dit alles. Om een ​​beetje te overdrijven: de stop()methode vernietigde simpelweg alles wat op zijn weg kwam. Het was alsof je het netsnoer uit het stopcontact trok om de computer uit te zetten. Ja, je kunt het gewenste resultaat krijgen. Maar iedereen weet dat de computer je na een paar weken niet meer dankbaar zal zijn dat je hem zo behandeld hebt. Daarom is de logica voor het onderbreken van threads gewijzigd in Java en wordt nu een speciale interrupt()methode gebruikt.

De methode Thread.interrupt()

Wat gebeurt er als de interrupt()methode wordt aangeroepen op een thread? Er zijn 2 mogelijkheden:
  1. Als het object in de wachtstand stond, bijvoorbeeld vanwege de joinof sleepmethodes, dan wordt het wachten onderbroken en zal het programma een InterruptedException.
  2. Als de thread in werkende staat was, interruptedwordt de booleaanse vlag op het object gezet.
Maar we moeten de waarde van deze vlag op het object controleren en het werk zelf correct voltooien! Daarom Threadheeft de klas de boolean isInterrupted()methode. Laten we teruggaan naar het klokvoorbeeld dat in een les in de basiscursus stond. Voor het gemak hebben we het iets vereenvoudigd:

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");
       }
   }
}
In dit geval wordt de klok gestart en begint elke seconde te tikken. In de 10e seconde onderbreken we de draad van de klok. Zoals u al weet, is het resultaat een InterruptedException. Dit is een gecontroleerde uitzondering, dus we kunnen het gemakkelijk opvangen en onze logica uitvoeren om het programma te voltooien. En dat is precies wat we deden. Dit is ons resultaat: Tick Tick Tick Tcik Tick Tick Tick Tick Tick De thread werd onderbroken Dit is het einde van onze inleiding tot de Threadbelangrijkste methoden van de klas. Succes!
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION