Metóda Thread.join () v Jave

1. Prehľad

V tomto tutoriáli si rozoberieme rôzne možnosti pripojiť sa () metódy v Závit trieda. Pôjdeme do podrobností o týchto metódach a niekoľkých príkladoch kódu.

Ako počkaj () a oznámiť () metódy, pripojiť sa () je ďalší mechanizmus synchronizácie medzi vláknami.

V tejto príručke sa môžete rýchlo pozrieť, aby ste sa o nej dozvedeli viac počkaj () a upozorniť ().

2. The Thread.join () Metóda

Metóda spojenia je definovaná v Závit trieda:

public final void join () vyvolá InterruptedException

Čaká na umretie tohto vlákna.

Keď vyvoláme pripojiť sa () metóda na vlákne, volajúce vlákno prejde do stavu čakania. Zostáva v čakajúcom stave, kým sa vlákno, na ktoré sa odkazuje, neukončí.

Toto správanie môžeme vidieť v nasledujúcom kóde:

trieda SampleThread rozširuje vlákno {public int processingCount = 0; SampleThread (int processingCount) {this.processingCount = processingCount; LOGGER.info ("Vlákno vytvorené"); } @Override public void run () {LOGGER.info ("Thread" + this.getName () + "started"); while (processingCount> 0) {try {Thread.sleep (1000); } catch (InterruptedException e) {LOGGER.info ("vlákno" + toto.getName () + "prerušené"); } countCount--; } LOGGER.info ("Vlákno" + this.getName () + "ukončenie"); }} @Test public void givenStartedThread_whenJoinCalled_waitsTillCompletion () hodí InterruptedException {Thread t2 = new SampleThread (1); t2.start (); LOGGER.info ("Vyvolávanie vstupu"); t2.join (); LOGGER.info ("Vrátené z pripojenia"); assertFalse (t2.isAlive ()); } 

Pri vykonávaní kódu by sme mali očakávať výsledky podobné nasledujúcim:

INFO: Vlákno vytvorené INFO: Vyvolávanie spojenia INFO: Vlákno Vlákno-1 spustené INFO: Vlákno Vlákno-1 vystupujúce INFO: Vrátené zo spojenia

The pripojiť sa () metóda sa môže tiež vrátiť, ak bolo referenčné vlákno prerušené. V takom prípade metóda hodí Prerušená výnimka.

Nakoniec ak je odkazované vlákno už ukončené alebo nebolo spustené, volanie na pripojiť sa () metóda sa vráti okamžite.

Vlákno t1 = nové SampleThread (0); t1.join (); // vráti sa okamžite

3. Thread.join () Metódy s časovým limitom

The pripojiť sa () metóda bude čakať, ak je odkazované vlákno blokované alebo jeho spracovanie trvá príliš dlho. To sa môže stať problémom, pretože volajúce vlákno prestane reagovať. Na riešenie týchto situácií používame preťažené verzie servera pripojiť sa () metóda, ktorá nám umožňuje určiť časový limit.

Existujú dve časované verzie, ktoré preťažujú pripojiť sa () metóda:

„Verejné konečné neplatné pripojenie (dlhé millis) hodí InterruptedException

Maximálne počká millis milisekundy, aby toto vlákno zomrelo. Časový limit 0 znamená čakať večne. “

„Verejné konečné neplatné pripojenie (dlhé millis, intnanos) hodí InterruptedException

Maximálne počká millis milisekundy plus nanos nanosekundy, aby táto niť zomrela. “

Môžeme použiť načasovaný pripojiť sa () ako je uvedené nižšie:

@Test public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout () vyvolá InterruptedException {Thread t3 = new SampleThread (10); t3.start (); t3.join (1000); assertTrue (t3.isAlive ()); } 

V takom prípade volajúce vlákno čaká zhruba 1 sekundu, kým vlákno t3 skončí. Ak vlákno t3 v tomto časovom období nedokončí, pripojiť sa () metóda vráti riadenie volajúcej metóde.

Načasované pripojiť sa () je časovo závislá od OS. To teda nemôžeme predpokladať pripojiť sa () počká presne tak dlho, ako je uvedené.

4. Thread.join () Metódy a synchronizácia

Okrem čakania na ukončenie volania na pripojiť sa () metóda má synchronizačný efekt. join () vytvorí vzťah „stane sa predtým“:

„Všetky akcie vo vlákne sa uskutočnia skôr, ako sa akékoľvek iné vlákno úspešne vráti zo spojenia () v tomto vlákne.“

To znamená, že keď vlákno t1 volá t2.join (), potom sú všetky zmeny vykonané pomocou t2 viditeľné v t1 po návrate. Ak sa však nedovoláme pripojiť sa () alebo používame iné synchronizačné mechanizmy, nemáme žiadnu záruku, že zmeny v druhom vlákne budú viditeľné pre aktuálne vlákno, aj keď bolo druhé vlákno dokončené.

Preto, aj keď pripojiť sa () volanie metódy na vlákno v ukončenom stave sa vráti okamžite, v niektorých situáciách ho ešte musíme zavolať.

Nižšie vidíme príklad nesprávne synchronizovaného kódu:

SampleThread t4 = nový SampleThread (10); t4.start (); // nie je zaručené, že sa zastaví, aj keď skončí t4. do {} while (t4.processingCount> 0);

Pre správnu synchronizáciu vyššie uvedeného kódu môžeme pridať časovanú t4.join () vo vnútri slučky alebo použiť iný synchronizačný mechanizmus.

5. Záver

pripojiť sa () metóda je celkom užitočná na synchronizáciu medzi vláknami. V tomto článku sme diskutovali o pripojiť sa () metódy a ich správanie. Skontrolovali sme tiež kód pomocou pripojiť sa () metóda.

Celý zdrojový kód nájdete ako vždy na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found