Implementatie van een uitvoerbare versus verlenging van een discussielijn

1. Inleiding

“Moet ik een Runnable of verleng de Draad klasse"? is een vrij veel voorkomende vraag.

In dit artikel zullen we zien welke aanpak in de praktijk zinvoller is en waarom.

2. Met behulp van Draad

Laten we eerst een SimpleThread klasse die zich uitstrekt Draad:

openbare klasse SimpleThread breidt Thread {privé String-bericht uit; // standaard logger, constructor @ Override public void run () {log.info (bericht); }}

Laten we ook kijken hoe we een thread van dit type kunnen uitvoeren:

@Test openbare leegte gegevenAThread_whenRunIt_thenResult () gooit uitzondering {Thread thread = nieuwe SimpleThread ("SimpleThread uitgevoerd met Thread"); thread.start (); thread.join (); }

We kunnen ook een ExecutorService om de thread uit te voeren:

@Test openbare leegte gegevenAThread_whenSubmitToES_thenResult () gooit uitzondering {executorService.submit (nieuwe SimpleThread ("SimpleThread uitgevoerd met ExecutorService")). Get (); }

Dat is nogal wat code voor het uitvoeren van een enkele logboekbewerking in een aparte thread.

Merk ook op dat SimpleThread kan geen andere klasse uitbreiden, aangezien Java geen meervoudige overerving ondersteunt.

3. Implementeren van een Runnable

Laten we nu een eenvoudige taak maken die het java.lang.Runnable koppel:

klasse SimpleRunnable implementeert Runnable {privé String-bericht; // standaard logger, constructor @ Override public void run () {log.info (bericht); }}

Bovenstaande SimpleRunnable is slechts een taak die we in een aparte thread willen uitvoeren.

Er zijn verschillende benaderingen die we kunnen gebruiken om het uit te voeren; een van hen is om de Draad klasse:

@Test openbare leegte gegevenRunnable_whenRunIt_thenResult () gooit uitzondering {Thread thread = nieuwe Thread (nieuwe SimpleRunnable ("SimpleRunnable uitgevoerd met Thread")); thread.start (); thread.join (); }

We kunnen zelfs een ExecutorService:

@Test openbare ongeldig gegevenARunnable_whenSubmitToES_thenResult () gooit uitzondering {executorService.submit (nieuwe SimpleRunnable ("SimpleRunnable uitgevoerd met ExecutorService")). Get (); }

We kunnen er meer over lezen ExecutorService hier.

Omdat we nu een interface implementeren, zijn we vrij om een ​​andere basisklasse uit te breiden als dat nodig is.

Beginnend met Java 8, wordt elke interface die een enkele abstracte methode blootlegt, behandeld als een functionele interface, waardoor het een geldig lambda-expressiedoel wordt.

We kunnen het bovenstaande herschrijven Runnable code met behulp van een lambda-uitdrukking:

@Test openbare leegte gegevenARunnableLambda_whenSubmitToES_thenResult () gooit uitzondering {executorService.submit (() -> log.info ("Lambda uitvoerbaar uitgevoerd!")); }

4. Runnable of Draad?

Simpel gezegd, we moedigen over het algemeen het gebruik van aan Runnable over- Draad:

  • Bij het verlengen van de Draad class, overschrijven we geen van de methoden ervan. In plaats daarvan overschrijven we de methode van Loopbaar (welke Draad gebeurt te implementeren). Dit is een duidelijke schending van IS-A Draad beginsel
  • Een implementatie maken van Runnable en het doorgeven aan de Draad klasse maakt gebruik van compositie en niet van overerving - wat flexibeler is
  • Na het verlengen van het Draad klasse, we kunnen geen andere klasse uitbreiden
  • Vanaf Java 8, Runnables kan worden weergegeven als lambda-uitdrukkingen

5. Conclusie

In deze korte tutorial hebben we gezien hoe Runnable is doorgaans een betere benadering dan het uitbreiden van de Draad klasse.

De code voor dit bericht is te vinden op GitHub.