Som backend-ingenjör står vi inför situationer för att behandla data asynkront. Låt oss idag se hur det görs i java och olika sätt att göra det på.

Thread

Den mycket grundläggande men ändå så kraftfulla komponenten i Java samtidighet är Thread. Javas tråd är faktiskt associerad med tråden i operativsystemet. Det mycket grundläggande sättet att skapa en Thread är genom att förlänga den och åsidosätta run :

Att starta tråden orsakar run() att kallas.
Du kan fråga; ja, tråden har massor av andra metoder som kan åsidosättas:

  • I de flesta fall vill vi inte åsidosätta andra metoder för tråden.
  • När vi förlänger Thread klassen, förlorar den utökade klassen sin förmåga att utöka ytterligare eftersom Java inte stöder flera arv.
  • Varje tråd har sitt eget objekt när vi förlänger den, och det är inte bra för minneshälsan när det finns massor av Objects of the extended Thread skapas.

Java löser dessa problem med Runnable-gränssnittet. Faktiskt, Thread har en överbelastad metod som tar Runnable.

Runnable

Runnable är ett gränssnitt som bara har en metod: run(). Ja, Runnable är ett funktionellt gränssnitt och dess instans kan skapas med lambda-funktionen. Ändå är det ett enkelt sätt att göra detta; för komplexa saker kanske vi skulle vilja implementera det. Se skillnaden här. Allt handlar om kravet:

Även om Runnable har en run(), det är inte en tråd utan bara en Java-klass tills den har tagits över av (överförs till) tråd. Starten av tråden orsakar det körbara objektets run() att kallas.

Japp, Java fick det löst i version 1.5, och det är Callable.

Callable<V>

Callable är ett generiskt gränssnitt. Varför? Kör detta kommando av returvärdet som det generiska kör detta kommando. Callable är för ett funktionellt gränssnitt och call() är den enda metoden, en metod utan argument som kastar undantag och returnerar generisk kör detta kommandovärde.

Implementerande Callable är mycket lik Runnable:

Se här, anropet behandlar data och returnerar ett värde som kan samlas in efter exekvering. Men är det stor skillnad på att åberopa det? Vi använder ExecutorService att åberopa och Future för att behålla resultatet. Låt oss prata om varför.

Som du kan se finns det inget kontrollerat beteende för att skapa och köra trådarna (körbara eller anropbara också). Vi kanske vill kontrollera antalet trådar som körs åt gången eftersom var och en av dem associeras med OS:s trådar. Antalet trådar vi kör bör vara mindre än antalet tillgängliga CPU-kärnor. Sammantaget löser Java det genom ExecutorService gränssnitt.
Ovan finns en informationsartikel om Asynkron programmering i Java: Del I.
Kontakta oss gärna via kommentarsfältet, om du har några frågor angående instruktionerna vi delade ovan.