Runnable vs. Callable in Java

Overview

Javan alkuajoista lähtien monilukutaito on ollut tärkeä osa kieltä. Runnable on monisäikeisten tehtävien esittämiseen tarkoitettu ydinliittymä ja Callable on paranneltu versio Runnablesta, joka lisättiin Java 1.5: ssä.

tässä artikkelissa tutustutaan molempien rajapintojen eroihin ja sovelluksiin.

Suoritusmekanismi

molemmat liitännät on suunniteltu edustamaan tehtävää, joka voidaan suorittaa useilla säikeillä. Suoritettavat tehtävät voidaan suorittaa Langanluokalla tai Suorittajapalvelulla, kun taas soitettavat tehtävät voidaan suorittaa vain jälkimmäisellä.

Palautusarvot

katsotaanpa tarkemmin, miten nämä rajapinnat käsittelevät palautusarvoja.

3.1. Kun Runnable

Runnable interface on funktionaalinen liitäntä ja siinä on yhden ajon() menetelmä, joka ei hyväksy mitään parametreja eikä palauta mitään arvoja.

tämä soveltuu tilanteisiin, joissa emme etsi langan suorituksen tulosta, esimerkiksi saapuvien tapahtumien kirjaaminen:

public interface Runnable { public void run();}

ymmärretään tämä esimerkillä:

public class EventLoggingTask implements Runnable{ private Logger logger = LoggerFactory.getLogger(EventLoggingTask.class); @Override public void run() { logger.info("Message"); }}

tässä esimerkissä säie vain lukee viestin jonosta ja kirjaa sen lokitiedostoon. Tehtävästä ei palauteta arvoa; tehtävä voidaan käynnistää ExecutorService-palvelun avulla:

public void executeTask() { executorService = Executors.newSingleThreadExecutor(); Future future = executorService.submit(new EventLoggingTask()); executorService.shutdown();}

tällöin tulevalla esineellä ei ole mitään arvoa.

3.2. Jossa soitettava

soitettava rajapinta on yleinen rajapinta, joka sisältää yhden puhelun () menetelmän-joka palauttaa yleisen arvon V:

public interface Callable<V> { V call() throws Exception;}

Let ’ s On tarkastella laskettaessa factorial luvun:

public class FactorialTask implements Callable<Integer> { int number; // standard constructors public Integer call() throws InvalidParamaterException { int fact = 1; // ... for(int count = number; count > 1; count--) { fact = fact * count; } return fact; }}

kutsumenetelmän() tulos palautetaan tulevaan objektiin:

@Testpublic void whenTaskSubmitted_ThenFutureResultObtained(){ FactorialTask task = new FactorialTask(5); Future<Integer> future = executorService.submit(task); assertEquals(120, future.get().intValue());}

poikkeusten käsittely

katsotaan, kuinka sopivia ne ovat poikkeusten käsittelyyn.

4.1. Kun Runnable

koska menetelmän allekirjoituksessa ei ole määritelty” heitto ” – lauseketta, ei ole mitään keinoa lisätä muita tarkistettuja poikkeuksia.

4.2. Kun Callable

Callable ’s call () – menetelmä sisältää ”heittää poikkeus” – lausekkeen, joten voimme helposti levittää tarkistettuja poikkeuksia edelleen:

public class FactorialTask implements Callable<Integer> { // ... public Integer call() throws InvalidParamaterException { if(number < 0) { throw new InvalidParamaterException("Number should be positive"); } // ... }}

jos soitettava ajetaan Suorittajapalvelulla, poikkeukset kerätään tulevaan objektiin, jonka voi tarkistaa soittamalla puhelun tulevaisuuteen.get () – menetelmä. Tämä heittää ExecutionException-joka kietoo alkuperäisen poikkeuksen:

@Test(expected = ExecutionException.class)public void whenException_ThenCallableThrowsIt() { FactorialCallableTask task = new FactorialCallableTask(-5); Future<Integer> future = executorService.submit(task); Integer result = future.get().intValue();}

yllä olevassa testissä, ExecutionException heitetään, koska ohitamme virheellinen numero. Voimme kutsua getCause() menetelmä tämän poikkeuksen objektin saada alkuperäisen tarkistetaan poikkeus.

jos emme tee kutsua tulevan luokan get () – menetelmään – niin kutsumenetelmällä heitettyä poikkeusta () ei raportoida takaisin, ja tehtävä merkitään silti suoritetuksi:

@Testpublic void whenException_ThenCallableDoesntThrowsItIfGetIsNotCalled(){ FactorialCallableTask task = new FactorialCallableTask(-5); Future<Integer> future = executorService.submit(task); assertEquals(false, future.isDone());}

yllä oleva testi läpäisee onnistuneesti, vaikka olemme heittäneet poikkeuksen parametrin negatiivisille arvoille Factorialcallabletaskille.

johtopäätös

tässä artikkelissa olemme tutkineet ajettavien ja soitettavien rajapintojen eroja.

kuten aina, tämän artikkelin koko koodi löytyy Githubista.

Aloita Spring 5: n ja Spring Boot 2: n avulla Learn Spring-kurssin avulla:

>> tutustu kurssiin

Vastaa

Sähköpostiosoitettasi ei julkaista.

Previous post Nitriili
Next post Julian Morris on ”New Girl” = paras Idea koskaan