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