Paralelní běh pod kontrolou

Nedávno jsem si hrál se zátěžovými testy komunikace přes síť. Protože se nedal použít žádný standardní nástroj, byl jsem nucen naimplementovat paralelní běh několika vláken ručně. Naštěstí je součástí Javy od verze 5 balík java.util.concurrent, který nám práci výrazně usnadní.

Představme si situaci, kdy máme úkol, který je dobře paralelizovatelný. Například hodně malých nezávislých výpočtů nebo stažení hodně souborů po síti. Tyto malé úlohy chceme spustit paralelně proto, abychom naplno využili zdroje (všechny procesory, šířku přenosového pásma atp.) Zároveň ale chceme omezit počet vláken, které běží najednou, aby režie na správu vláken nebyla zbytečně velká. Nemá smysl spouště zároveň sto výpočetně náročných vláken, když máme jenom dva procesory. V Jave 5 máme k dispozici třídu Executors. Ta nám umožní vytvořit implementace rozhraní ExecutorService, určené ke spouštění vláken. Výše popsaný úkol vyřešíme jednoduše takto:



01 ExecutorService executor = Executors.newFixedThreadPool(8);//8 threads
02     for (int i=0;i<100; i++)
03     {
04       executor.execute(new Runnable(){
05         public void run() {
06           paralelTask();//neco co chceme spustit paralelne  
07         }
08       });
09     }
10     executor.shutdown();//prestane prijimat nove ukoly
11     executor.awaitTermination(60, TimeUnit.SECONDS);

Na prvním řádku si necháme vytvořit thread pool s osmi vlákny. Poté mu zadáme 100 úkolů ke zpracování. Implementace ExecutorService se už postará o jejich spuštění. Hlavní vlákno pokračuje v běhu dál. Pokud chceme počkat až na konec výpočtu, řekneme executorovi aby se začal vypínat (řádek 10). Executor tím pádem přestane přijímat nové úkoly, ale pokračuje ve vykonávání již zadaných. Počkat na jejich dokončení můžeme počkat pomocí metody awaitTermination. Té musíme říci, jak dlouho má na dokončení čekat. Pokud se vykonání do specifikovaného času nestihne, metoda awaitTermination vrátí false.

One thought on “Paralelní běh pod kontrolou

Comments are closed.