Livssyklus for en tråd i Java

1. Introduksjon

I denne artikkelen vil vi diskutere i detalj et kjernekonsept i Java - livssyklusen til en tråd.

Vi bruker et raskt illustrert diagram og, selvfølgelig, praktiske kodebiter for å bedre forstå disse tilstandene under utførelsen av tråden.

For å komme i gang med å forstå tråder i Java, er denne artikkelen om å lage en tråd et godt sted å starte.

2. Multitrading i Java

På Java-språket drives multitrading av kjernekonseptet med en tråd. I løpet av livssyklusen går tråder gjennom forskjellige tilstander:

3. Livssyklus for en tråd i Java

De java.lang.Tråd klasse inneholder en statisk stat enum - som definerer dets potensielle tilstander. I løpet av et gitt tidspunkt kan tråden bare være i en av disse tilstandene:

  1. NYHET - en nyopprettet tråd som ennå ikke har startet utførelsen
  2. RUNNABLE - enten kjører eller klar for kjøring, men det venter på ressurstildeling
  3. BLOKERT - venter på å anskaffe en skjermlås for å gå inn eller angi en synkronisert blokk / metode på nytt
  4. VENTER - venter på at en annen tråd skal utføre en bestemt handling uten tidsbegrensning
  5. TIMED_WAITING - venter på at en annen tråd skal utføre en bestemt handling i en spesifisert periode
  6. AVSLUTTET - har fullført henrettelsen

Alle disse tilstandene er dekket i diagrammet ovenfor; la oss nå diskutere hver av disse i detalj.

3.1. Ny

EN NYTråd (eller en født Tråd) er en tråd som er opprettet, men som ennå ikke er startet. Det forblir i denne tilstanden til vi begynner å bruke start() metode.

Følgende kodebit viser en nylig opprettet tråd som er i NY stat:

Runnable runnable = new NewState (); Tråd t = ny tråd (kan kjøres); Log.info (t.getState ());

Siden vi ikke har startet den nevnte tråden, er metoden t.getState () utskrifter:

NY

3.2. Kjørbar

Når vi har opprettet en ny tråd og kalt start() metode på det, er det flyttet fra NY til RUNNABLE stat. Tråder i denne tilstanden kjøres enten eller er klare til å kjøres, men de venter på ressurstildeling fra systemet.

I et miljø med flere tråder tildeler trådtidsplanleggeren (som er en del av JVM) en fast tid til hver tråd. Så det går i en bestemt periode, og deretter avgir kontrollen til andre RUNNABLE tråder.

La oss for eksempel legge til t.start () metode til vår forrige kode og prøv å få tilgang til den nåværende tilstanden:

Runnable runnable = new NewState (); Tråd t = ny tråd (kan kjøres); t.start (); Log.info (t.getState ());

Denne koden er mest sannsynlig for å returnere utdata som:

RUNNABLE

Merk at i dette eksemplet er det ikke alltid garantert at når kontrollen når t.getState (), vil det være fremdeles i RUNNABLE stat.

Det kan hende at den ble umiddelbart planlagt av Trådplanlegger og kan fullføre utførelsen. I slike tilfeller kan vi få en annen produksjon.

3.3. Blokkert

En tråd er i BLOKERT oppgi når den for øyeblikket ikke er kvalifisert for å kjøre. Den går inn i denne tilstanden når den venter på en skjermlås og prøver å få tilgang til en kodeseksjon som er låst av en annen tråd.

La oss prøve å gjengi denne tilstanden:

offentlig klasse BlockedState {offentlig statisk tomrom hoved (String [] args) kaster InterruptedException {Thread t1 = new Thread (new DemoThreadB ()); Tråd t2 = ny tråd (ny DemoThreadB ()); t1.start (); t2.start (); Tråd. Søvn (1000); Log.info (t2.getState ()); System.exit (0); }} klasse DemoThreadB implementerer Runnable {@Override public void run () {commonResource (); } offentlig statisk synkronisert tomrom commonResource () {while (true) {// Infinite loop for å etterligne tung prosessering // 't1' vil ikke forlate denne metoden // når 't2' prøver å legge inn denne}}}

I denne koden:

  1. Vi har laget to forskjellige tråder - t1 og t2
  2. t1 starter og går inn i det synkroniserte commonResource () metode; dette betyr at bare en tråd kan få tilgang til den; alle andre påfølgende tråder som prøver å få tilgang til denne metoden vil bli blokkert fra videre kjøring til den nåværende vil fullføre behandlingen
  3. Når t1 går inn i denne metoden, holdes den i en uendelig mens løkke; dette er bare for å etterligne tung prosessering slik at alle andre tråder ikke kan gå inn i denne metoden
  4. Nå når vi begynner t2, prøver den å gå inn i commonResource () metoden, som allerede nås av t1, og dermed, t2 vil bli holdt i BLOKERT stat

Å være i denne tilstanden, kaller vi t2.getState () og få utdataene som:

BLOKERT

3.4. Venter

En tråd er inne VENTER angi når den venter på at en annen tråd skal utføre en bestemt handling. I følge JavaDocs kan hvilken som helst tråd komme inn i denne tilstanden ved å ringe en av følgende tre metoder:

  1. object.wait ()
  2. thread.join () eller
  3. LockSupport.park ()

Legg merke til at i vente() og bli med() - vi definerer ikke noen tidsavbruddsperiode, da dette scenariet blir dekket i neste avsnitt.

Vi har en egen veiledning som i detalj diskuterer bruken av vente(), gi beskjed() og notifyAll ().

For nå, la oss prøve å gjengi denne tilstanden:

offentlig klasse WaitingState implementerer Runnable {public static Thread t1; public static void main (String [] args) {t1 = new Thread (new WaitingState ()); t1.start (); } public void run () {Thread t2 = new Thread (new DemoThreadWS ()); t2.start (); prøv {t2.join (); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); Log.error ("Tråden avbrutt", e); }}} klasse DemoThreadWS implementerer Runnable {public void run () {try {Thread.sleep (1000); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); Log.error ("Tråden avbrutt", e); } Log.info (WaitingState.t1.getState ()); }}

La oss diskutere hva vi gjør her:

  1. Vi har opprettet og startet t1
  2. t1 skaper en t2 og starter den
  3. Mens behandlingen av t2 fortsetter, ringer vi t2. bli med (), dette setter t1 i VENTER tilstand til t2 er ferdig utført
  4. Siden t1 venter på t2 for å fullføre, ringer vi t1.getState () fra t2

Resultatet her er, som du forventer:

VENTER

3.5. Tidsbestemt venting

En tråd er inne TIMED_WAITING angi når den venter på at en annen tråd skal utføre en bestemt handling innen en bestemt tid.

I følge JavaDocs er det fem måter å sette en tråd på TIMED_WAITING stat:

  1. thread.sleep (long millis)
  2. vent (int timeout) eller vent (int timeout, int nanos)
  3. thread.join (lang millis)
  4. LockSupport.parkNanos
  5. LockSupport.parkUntil

For å lese mer om forskjellene mellom vente() og søvn() i Java, ta en titt på denne dedikerte artikkelen her.

For nå, la oss prøve å reprodusere raskt denne tilstanden:

offentlig klasse TimedWaitingState {public static void main (String [] args) kaster InterruptedException {DemoThread obj1 = new DemoThread (); Tråd t1 = ny tråd (obj1); t1.start (); // Følgende søvn vil gi nok tid til ThreadScheduler // til å starte behandlingen av tråden t1 Thread.sleep (1000); Log.info (t1.getState ()); }} klasse DemoThread implementerer Runnable {@Override public void run () {try {Thread.sleep (5000); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); Log.error ("Tråden avbrutt", e); }}}

Her har vi opprettet og startet en tråd t1 som settes i hviletilstand med en tidsavbruddsperiode på 5 sekunder; utgangen vil være:

TIMED_WAITING

3.6. Avsluttet

Dette er tilstanden til en død tråd. Det er i AVSLUTTET angi når den enten er ferdig utført eller ble avsluttet unormalt.

Vi har en dedikert artikkel som diskuterer forskjellige måter å stoppe tråden på.

La oss prøve å oppnå denne tilstanden i følgende eksempel:

offentlig klasse TerminatedState implementerer Runnable {public static void main (String [] args) throw InterruptedException {Thread t1 = new Thread (new TerminatedState ()); t1.start (); // Følgende hvilemetode vil gi nok tid til // tråd t1 til å fullføre Thread.sleep (1000); Log.info (t1.getState ()); } @ Override public void run () {// Ingen behandling i denne blokken}}

Her, mens vi har startet tråden t1, den neste uttalelsen Thread.sleep (1000) gir nok tid til t1 å fullføre, og dette programmet gir oss resultatet som:

AVSLUTTET

I tillegg til trådtilstanden, kan vi sjekke er i live() metode for å avgjøre om tråden er i live eller ikke. For eksempel hvis vi kaller er i live() metode på denne tråden:

Assert.assertFalse (t1.isAlive ());

Det kommer tilbake falsk. Enkelt sagt, en tråd er i live hvis og bare hvis den har blitt startet og har ennå ikke død.

4. Konklusjon

I denne opplæringen lærte vi om livssyklusen til en tråd i Java. Vi så på alle seks stater definert av Tråd. Stat enum og gjengitt dem med raske eksempler.

Selv om kodebitene vil gi samme utgang i nesten alle maskiner, kan vi i noen unntakstilfeller få noen forskjellige utganger, ettersom den eksakte oppførselen til trådplanleggeren ikke kan bestemmes.

Og som alltid er kodebitene som brukes her, tilgjengelige på GitHub.


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