Metoda Thread.join () u Javi

1. Pregled

U ovom uputstvu razgovarat ćemo o različitim pridružiti() metode u Nit razred. Ući ćemo u detalje ovih metoda i neki primjer koda.

Poput čekati() i notify () metode, pridružiti() je još jedan mehanizam sinkronizacije među nitima.

Možete brzo pogledati ovaj vodič da biste pročitali više o njemu čekati() i obavijestiti().

2. The Thread.join () Metoda

Metoda spajanja definirana je u Nit razred:

javno konačno void join () baca InterruptedException

Čeka da ova nit umre.

Kada zazivamo pridružiti() metodom na niti, pozivajuća nit prelazi u stanje čekanja. Ostaje u stanju čekanja dok se navedena nit ne završi.

Ovo ponašanje možemo vidjeti u sljedećem kodu:

klasa SampleThread proširuje Thread {public int processingCount = 0; SampleThread (int processingCount) {this.processingCount = processingCount; LOGGER.info ("Tema stvorena"); } @Override public void run () {LOGGER.info ("Thread" + this.getName () + "started"); while (processingCount> 0) {try {Thread.sleep (1000); } catch (InterruptedException e) {LOGGER.info ("Thread" + this.getName () + "interrupted"); } processingCount--; } LOGGER.info ("Nit" + this.getName () + "izlaz"); }} @Test javna praznina givenStartedThread_whenJoinCalled_waitsTillCompletion () baca InterruptedException {Thread t2 = new SampleThread (1); t2.start (); LOGGER.info ("Pozivanje na pridruživanje"); t2.join (); LOGGER.info ("Vraćeno iz pridruživanja"); assertFalse (t2.isAlive ()); } 

Prilikom izvršavanja koda trebali bismo očekivati ​​rezultate slične sljedećim:

INFO: Tema stvorena INFO: Pozivanje na pridruživanje INFO: Pokrenuta nit Thread-1 INFO: Thread Thread-1 izlazi iz INFO: Vraćeno iz join

The pridružiti() metoda se također može vratiti ako je referencirana nit prekinuta. U ovom slučaju, metoda baca InterruptedException.

Konačno, ako je referencirana nit već prekinuta ili nije pokrenuta, poziv na pridružiti() metoda se odmah vraća.

Navoj t1 = novi SampleThread (0); t1.join (); // vraća se odmah

3. Thread.join () Metode s vremenskim ograničenjem

The pridružiti() metoda nastavit će čekati ako je navedena nit blokirana ili obrada predugo traje. To može postati problem jer nit poziva neće reagirati. Da bismo riješili ove situacije, koristimo preopterećene verzije pridružiti() metoda koja nam omogućuje da odredimo vremensko ograničenje.

Postoje dvije vremenske verzije koje preopterećuju pridružiti() metoda:

“Javno konačno nevažeće pridruživanje (dugo milis) baca InterruptedException

Čeka najviše milis milisekundi da ova nit umre. Vremensko ograničenje od 0 znači zauvijek čekati. "

“Javno konačno nevažeće pridruživanje (dugo milis, međnanos) baca InterruptedException

Čeka najviše milis milisekunde plus nanos nanosekunde da ova nit umre. "

Možemo koristiti vremenski ograničeno pridružiti() kao ispod:

@Test javna praznina givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout () baca InterruptedException {Thread t3 = new SampleThread (10); t3.start (); t3.priključiti se (1000); assertTrue (t3.isAlive ()); } 

U ovom slučaju, nit koja poziva čeka približno 1 sekundu da završi nit t3. Ako se nit t3 ne završi u ovom vremenskom razdoblju, pridružiti() metoda vraća kontrolu pozivajućoj metodi.

Vremenski pridružiti() ovisi o OS-u za vrijeme. Dakle, to ne možemo pretpostaviti pridružiti() čekat će točno onoliko koliko je određeno.

4. Thread.join () Metode i sinkronizacija

Osim čekanja do prekida, pozivanje pridružiti() metoda ima učinak sinkronizacije. join () stvara odnos prije-prije:

"Sve se radnje u niti događaju - prije nego što se bilo koja druga nit uspješno vrati iz join () na toj niti."

To znači da kada nit t1 pozove t2.join (), tada su sve promjene učinjene od strane t2 vidljive u t1 po povratku. Međutim, ako se ne zazovemo pridružiti() ili koristimo druge mehanizme sinkronizacije, nemamo nikakvo jamstvo da će promjene u drugoj niti biti vidljive trenutnoj niti, čak i ako je druga nit završena.

Stoga, iako pridružiti() poziv metode u nit u zaustavljenom stanju vraća se odmah, još uvijek je trebamo pozvati u nekim situacijama.

Primjer nepravilno sinkroniziranog koda možemo vidjeti u nastavku:

SampleThread t4 = novi SampleThread (10); t4.start (); // nije zajamčeno da će se zaustaviti čak i ako t4 završi. do {} while (t4.processingCount> 0);

Da bismo pravilno sinkronizirali gornji kôd, možemo dodati vremenski ograničen t4.join () unutar petlje ili upotrijebite neki drugi mehanizam sinkronizacije.

5. Zaključak

pridružiti() metoda je vrlo korisna za sinkronizaciju među nitima. U ovom smo članku razgovarali o pridružiti() metode i njihovo ponašanje. Također smo pregledali kod koristeći pridružiti() metoda.

Kao i uvijek, puni izvorni kod možete pronaći na GitHubu.