Implementácia spustiteľného programu vs rozšírenie vlákna
1. Úvod
"Mám implementovať a Spustiteľné alebo predĺžiť Závit trieda"? je celkom častá otázka.
V tomto článku uvidíme, ktorý prístup má v praxi väčší zmysel a prečo.
2. Pomocou Závit
Najprv si zadefinujme a SimpleThread trieda, ktorá sa rozširuje Závit:
verejná trieda SimpleThread rozširuje vlákno {súkromná reťazcová správa; // štandardný záznamník, konštruktor @Override public void run () {log.info (správa); }}
Pozrime sa tiež, ako môžeme spustiť vlákno tohto typu:
@ Test public void givenAThread_whenRunIt_thenResult () vyvolá výnimku {Thread thread = new SimpleThread ("SimpleThread executed using Thread"); thread.start (); thread.join (); }
Môžeme tiež použiť ExecutorService vykonať vlákno:
@Test public void givenAThread_whenSubmitToES_thenResult () vyvolá výnimku {executorService.submit (nový SimpleThread ("SimpleThread vykonaný pomocou ExecutorService")). Get (); }
To je pomerne veľa kódu na spustenie jednej operácie protokolu v samostatnom vlákne.
Pamätajte tiež na to SimpleThread nemôže rozšíriť inú triedu, pretože Java nepodporuje viacnásobné dedenie.
3. Implementácia a Spustiteľné
Poďme si teraz vytvoriť jednoduchú úlohu, ktorá implementuje java.lang.Runnable rozhranie:
trieda SimpleRunnable implementuje Runnable {private String message; // štandardný záznamník, konštruktor @Override public void run () {log.info (správa); }}
Vyššie uvedené SimpleRunnable je len úloha, ktorú chceme spustiť v samostatnom vlákne.
Na jeho spustenie môžeme použiť rôzne prístupy; jedným z nich je použitie Závit trieda:
@Test public void givenRunnable_whenRunIt_thenResult () vyvolá výnimku {Thread thread = new Thread (new SimpleRunnable ("SimpleRunnable executed using Thread")); thread.start (); thread.join (); }
Môžeme dokonca použiť znak ExecutorService:
@ Test public void givenARunnable_whenSubmitToES_thenResult () vyvolá výnimku {executorService.submit (nový SimpleRunnable ("SimpleRunnable vykonaný pomocou ExecutorService")). Get (); }
Môžeme sa dočítať viac o ExecutorService tu.
Pretože teraz implementujeme rozhranie, môžeme v prípade potreby rozšíriť ďalšiu základnú triedu.
Počnúc jazykom Java 8 sa s akýmkoľvek rozhraním, ktoré sprístupňuje jednu abstraktnú metódu, zaobchádza ako s funkčným rozhraním, ktoré z neho robí platný cieľ výrazu lambda.
Vyššie uvedené môžeme prepísať Spustiteľné kód pomocou výrazu lambda:
@ Test public void givenARunnableLambda_whenSubmitToES_thenResult () vyvolá výnimku {executorService.submit (() -> log.info ("spustiteľný súbor Lambda spustený!")); }
4. Spustiteľné alebo Závit?
Jednoducho povedané, všeobecne podporujeme používanie Spustiteľné cez Závit:
- Pri rozširovaní Závit triedy, neprepisujeme žiadnu z jej metód. Namiesto toho prepíšeme metódu Spustiteľné (ktoré Závit stane sa implementovať). Toto je zjavné porušenie IS-A Závit princíp
- Vytvára sa implementácia Spustiteľné a odovzdať ho Závit trieda využíva zloženie a nie dedičstvo - čo je pružnejšie
- Po predĺžení Závit triedy, nemôžeme rozšíriť žiadnu inú triedu
- Od verzie Java 8, Runnables môžu byť vyjadrené ako výrazy lambda
5. Záver
V tomto rýchlom návode sme videli, ako sa implementuje Spustiteľné je zvyčajne lepší prístup ako rozšírenie Závit trieda.
Kód tohto príspevku nájdete na GitHub.