Implementering af en kørbar vs udvidelse af en tråd

1. Introduktion

”Skal jeg implementere en Kan køres eller udvide Tråd klasse ”? er et ret almindeligt spørgsmål.

I denne artikel vil vi se, hvilken tilgang der giver mere mening i praksis, og hvorfor.

2. Brug Tråd

Lad os først definere en SimpleTråd klasse, der strækker sig Tråd:

offentlig klasse SimpleThread udvider tråd {privat strengbesked; // standard logger, constructor @ Override public void run () {log.info (meddelelse); }}

Lad os også se, hvordan vi kan køre en tråd af denne type:

@Test offentlig ugyldighed givenAThread_whenRunIt_thenResult () kaster undtagelse {thread thread = new SimpleThread ("SimpleThread udført ved hjælp af thread"); thread.start (); thread.join (); }

Vi kan også bruge en ExecutorService at udføre tråden:

@Test offentlig ugyldighed givenAThread_whenSubmitToES_thenResult () kaster undtagelse {executorService.submit (ny SimpleThread ("SimpleThread udført ved hjælp af ExecutorService")). Get (); }

Det er ret meget kode til at køre en enkelt logoperation i en separat tråd.

Bemærk også, at SimpleTråd kan ikke udvide nogen anden klasse, da Java ikke understøtter flere arv.

3. Implementering af a Kan køres

Lad os nu oprette en simpel opgave, der implementerer java.lang.Køres grænseflade:

klasse SimpleRunnable implementerer Runnable {private String message; // standard logger, constructor @ Override public void run () {log.info (meddelelse); }}

Ovenstående SimpleRunnable er bare en opgave, som vi vil køre i en separat tråd.

Der er forskellige tilgange, vi kan bruge til at køre det; en af ​​dem er at bruge Tråd klasse:

@Test offentlig ugyldighed givenRunnable_whenRunIt_thenResult () kaster undtagelse {Thread thread = new Thread (new SimpleRunnable ("SimpleRunnable executed using Thread")); thread.start (); thread.join (); }

Vi kan endda bruge en ExecutorService:

@Test offentlig ugyldighed givetARunnable_whenSubmitToES_thenResult () kaster Undtagelse {executorService.submit (ny SimpleRunnable ("SimpleRunnable udført ved hjælp af ExecutorService")). Get (); }

Vi kan læse mere om ExecutorService herinde.

Da vi nu implementerer en grænseflade, kan vi udvide en anden basisklasse, hvis vi har brug for det.

Startende med Java 8 behandles enhver grænseflade, der udsætter en enkelt abstrakt metode, som en funktionel grænseflade, hvilket gør det til et gyldigt lambda-ekspressionsmål.

Vi kan omskrive ovenstående Kan køres kode ved hjælp af et lambda-udtryk:

@Test offentlig ugyldighed givetARunnableLambda_whenSubmitToES_thenResult () kaster Undtagelse {executorService.submit (() -> log.info ("Lambda kørbar udført!")); }

4. Kan køres eller Tråd?

Kort sagt, vi opfordrer generelt brugen af Kan køres over Tråd:

  • Når du udvider Tråd klasse overstyrer vi ikke nogen af ​​dens metoder. I stedet tilsidesætter vi metoden til Kan køres (hvilken Tråd tilfældigvis implementerer). Dette er en klar overtrædelse af IS-A Tråd princip
  • Oprettelse af en implementering af Kan køres og videregiver det til Tråd klasse bruger komposition og ikke arv - hvilket er mere fleksibelt
  • Efter udvidelse af Tråd klasse, kan vi ikke udvide nogen anden klasse
  • Fra Java 8 og frem, Runnables kan repræsenteres som lambda-udtryk

5. Konklusion

I denne hurtige vejledning så vi, hvordan implementering Kan køres er typisk en bedre tilgang end at udvide Tråd klasse.

Koden til dette indlæg kan findes på GitHub.


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