Izvodljivo u odnosu na pozivno u Javi

1. Pregled

Od ranih dana Jave, multitreading je glavni aspekt jezika. Izvodljivo je jezgro sučelje predviđeno za predstavljanje zadataka s više niti i Pozivno je poboljšana verzija Izvodljivo koji je dodan u Javi 1.5.

U ovom ćemo članku istražiti razlike i primjenu oba sučelja.

2. Mehanizam izvršenja

Oba sučelja dizajnirana su da predstavljaju zadatak koji se može izvršiti s više niti. Izvodljivo zadaci se mogu izvoditi pomoću Nit razred ili ExecutorService dok Pozivi može se pokrenuti samo pomoću potonjeg.

3. Povratne vrijednosti

Pogledajmo dublje način na koji ta sučelja obrađuju povratne vrijednosti.

3.1. S Izvodljivo

The Izvodljivo sučelje je funkcionalno sučelje i ima jedan trčanje() metoda koja ne prihvaća nikakve parametre i ne vraća nikakve vrijednosti.

Ovo je prikladno za situacije u kojima ne tražimo rezultat izvršenja niti, na primjer, bilježenje dolaznih događaja:

javno sučelje Runnable {public void run (); }

Shvatimo to na primjeru:

javna klasa EventLoggingTask implementira Runnable {private Logger logger = LoggerFactory.getLogger (EventLoggingTask.class); @Preuzmi javno void run () {logger.info ("Poruka"); }}

U ovom primjeru nit će samo pročitati poruku iz reda i prijaviti je u datoteku dnevnika. Iz zadatka se ne vraća vrijednost; zadatak se može pokrenuti pomoću Usluga izvršitelja:

javna praznina executeTask () {executorService = Executors.newSingleThreadExecutor (); Buduća budućnost = executorService.submit (novi EventLoggingTask ()); executorService.shutdown (); }

U ovom slučaju, Budućnost objekt neće imati nikakvu vrijednost.

3.2. S Pozivno

The Pozivno sučelje je generičko sučelje koje sadrži jedan poziv() metoda - koja vraća generičku vrijednost V:

javno sučelje Callable {V call () baca iznimku; }

Pogledajmo izračunavanje faktorijela broja:

javna klasa FactorialTask ​​implementira Callable {int number; // standardni konstruktori public Integer call () baca InvalidParamaterException {int fact = 1; // ... for (int count = number; count> 1; count--) {fact = fact * count; } vratiti cinjenicu; }}

Rezultat poziv() metoda se vraća u roku od Budućnost objekt:

@Test public void whenTaskSubmitted_ThenFutureResultObtain () {FactorialTask ​​zadatak = novi FactorialTask ​​(5); Buduća budućnost = executorService.submit (zadatak); assertEquals (120, future.get (). intValue ()); }

4. Rukovanje iznimkama

Pogledajmo koliko su prikladni za rukovanje iznimkama.

4.1. S Izvodljivo

Budući da potpis metode nema navedenu klauzulu "bacanja",ne postoji način da se šire daljnje provjerene iznimke.

4.2. S Pozivno

Poziv koji se može pozvati () metoda sadrži „bacanja Iznimka " klauzula tako da provjerene iznimke možemo lako proširiti dalje:

javna klasa FactorialTask ​​implementira Callable {// ... public Integer call () baca InvalidParamaterException {if (number <0) {throw new InvalidParamaterException ("Number should be positive"); } // ...}}

U slučaju pokretanja a Može se nazvati upotrebom an ExecutorService, iznimke su prikupljene u Budućnost objekt, koji se može provjeriti pozivom na Future.get () metoda. Ovo će baciti ExecutionException - koja obavija izvornu iznimku:

@Test (očekuje se = ExecutionException.class) javna praznina kadaException_ThenCallableThrowsIt () {FactorialCallableTask zadatak = novi FactorialCallableTask (-5); Buduća budućnost = executorService.submit (zadatak); Cjelobrojni rezultat = future.get (). IntValue (); }

U gore navedenom testu, ExecutionException baca se dok prolazimo s nevaljanim brojem. Možemo nazvati getCause () metoda na ovom objektu iznimke kako bi se dobila izvorno provjerena iznimka.

Ako ne uputimo poziv dobiti() metoda Budućnost razred - onda izuzetak koji je bacio poziv() metoda neće biti vraćena, a zadatak će i dalje biti označen kao dovršen:

@Test public void whenException_ThenCallableDoesntThrowsItIfGetIsNotCalled () {FactorialCallableTask zadatak = novi FactorialCallableTask (-5); Buduća budućnost = executorService.submit (zadatak); assertEquals (false, future.isDone ()); }

Gornji test uspješno će proći iako smo izuzetak za negativne vrijednosti parametra postavili na FactorialCallableTask.

5. Zaključak

U ovom smo članku istražili razlike između Izvodljivo i Pozivno sučelja.

Kao i uvijek, cjeloviti kôd za ovaj članak dostupan je na GitHubu.


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