Runnable vs. Disponibilní v Java

Přehled

Od prvních dnů Java, multithreading byl hlavní aspekt jazyka. Runnable je základní rozhraní poskytované pro reprezentaci vícevláknových úkolů a Callable je vylepšená verze Runnable, která byla přidána v Javě 1.5.

v tomto článku prozkoumáme rozdíly a aplikace obou rozhraní.

prováděcí mechanismus

obě rozhraní jsou navržena tak, aby představovala úlohu, kterou lze provést více vlákny. Spustitelné úlohy lze spustit pomocí třídy Thread nebo ExecutorService, zatímco Callables lze spustit pouze pomocí druhé.

návratové hodnoty

podívejme se hlouběji na způsob, jakým tato rozhraní zpracovávají návratové hodnoty.

3.1. S Runnable

rozhraní Runnable je funkční rozhraní a má jeden run() metodu, která nepřijímá žádné parametry a nevrací žádné hodnoty.

to je vhodné pro situace, kdy nehledáme výsledek provádění podprocesu, například protokolování příchozích událostí:

public interface Runnable { public void run();}

Pojďme pochopit tento příklad:

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

V tomto příkladu, bude vlákno stačí si přečíst zprávu z fronty a ukládat je do souboru protokolu. Z úkolu není vrácena žádná hodnota; úkol lze spustit pomocí ExecutorService:

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

v tomto případě budoucí objekt nebude mít žádnou hodnotu.

3.2. S Callable

Callable interface je generické rozhraní obsahující metodu jednoho volání () – která vrací generickou hodnotu V:

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

podívejme se na výpočet faktoriálu čísla:

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; }}

výsledek volání() metoda se vrátil do Budoucího objektu:

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

Zpracování Výjimek

Pojďme se podívat, jak vhodné jsou pro zpracování výjimek.

4.1. S Runnable

protože podpis metody nemá zadanou klauzuli „hody“, neexistuje způsob, jak šířit další kontrolované výjimky.

4.2. S Callable

Callable ‚s call () metoda obsahuje klauzuli „hodí výjimku“, takže můžeme snadno šířit kontrolované výjimky dále:

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

v případě spuštění Callable pomocí ExecutorService se výjimky shromažďují v budoucím objektu, který lze zkontrolovat voláním do budoucnosti.get () metoda. Tím se vyvolá ExecutionException-která zabalí původní výjimku:

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

ve výše uvedeném testu je ExecutionException vyvolána, když předáváme neplatné číslo. Můžeme zavolat metodu getCause () na tomto objektu výjimky, abychom získali původní zaškrtnutou výjimku.

Pokud nechceme, aby volání get() metoda Budoucnosti třídy – pak výjimkou je vyvolána call() metoda není hlášena zpět, a úkol bude stále označen jako dokončený:

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

výše uvedený test projde úspěšně i přesto, že jsme vyvolána výjimka pro záporné hodnoty parametru na FactorialCallableTask.

Závěr

V tomto článku jsme prozkoumali rozdíly mezi Runnable a Disponibilní rozhraní.

jako vždy, kompletní kód pro tento článek je k dispozici více než na GitHub.

začínáme s Jarní 5 a na Jaře Boot 2, a to prostřednictvím Naučit Jarní kurz:

>> PODÍVEJTE se NA KURZ

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.

Previous post Nitril
Next post Julian Morris na ‚Nová Holka‘ = Nejlepší Nápad