Prioritné plánovanie úloh v Jave

1. Úvod

V prostredí s viacerými vláknami niekedy musíme naplánovať úlohy na základe vlastných kritérií, nielen na čas potrebný na ich vytvorenie.

Pozrime sa, ako to môžeme v Jave dosiahnuť - pomocou a Priorita blokovania.

2. Prehľad

Povedzme, že máme pracovné miesta, ktoré chceme vykonávať na základe ich priority:

verejná trieda Job implementuje Runnable {private String jobName; súkromná JobPriority jobPriority; @Override public void run () {System.out.println ("Job:" + jobName + "Priority:" + jobPriority); Závit. Spánok (1 000); // na simuláciu skutočného času vykonania} // štandardní zadávatelia a obstarávatelia}

Na demonštračné účely tlačíme názov úlohy a prioritu do súboru run () metóda.

Tiež sme pridali spánok () aby sme simulovali dlhšie bežiacu prácu; počas vykonávania úlohy sa v prioritnom fronte nahromadí viac úloh.

Nakoniec JobPriority je jednoduchý výčet:

verejné enum JobPriority {VYSOKÉ, STREDNÉ, NÍZKE}

3. Vlastné Komparátor

Musíme napísať komparátor definujúci naše vlastné kritériá; a v prostredí Java 8 je to triviálne:

Comparator.comparing (Job :: getJobPriority);

4. Prioritný plánovač úloh

Po dokončení všetkých nastavení teraz implementujme jednoduchý plánovač úloh - ktorý na hľadanie úloh v Priorita blokovania a vykoná ich:

verejná trieda PriorityJobScheduler {private ExecutorService priorityJobPoolExecutor; private ExecutorService priorityJobScheduler = Executors.newSingleThreadExecutor (); private PriorityBlockingQueue priorityQueue; public PriorityJobScheduler (Integer poolSize, Integer queueSize) {priorityJobPoolExecutor = Executors.newFixedThreadPool (poolSize); priorityQueue = new PriorityBlockingQueue (queueSize, Comparator.comparing (Job :: getJobPriority)); priorityJobScheduler.execute (() -> {while (true) {try {priorityJobPoolExecutor.execute (priorityQueue.take ());} catch (InterruptedException e) {// výnimka vyžaduje špeciálne zachádzanie;}}}); } public void scheduleJob (Job job) {priorityQueue.add (job); }}

Kľúčom je vytvorenie inštancie Priorita blokovania z Job typ s vlastným komparátorom. Ďalšia úloha, ktorá sa má vykonať, sa vyberie z frontu pomocou vziať () metóda, ktorá načíta a odstráni hlavu frontu.

Kód klienta teraz musí jednoducho zavolať na scheduleJob () - ktorý pridá úlohu do frontu. The priorityQueue.add () zařadí úlohu na vhodné miesto v porovnaní s existujúcimi úlohami vo fronte pomocou JobExecutionComparator.

Upozorňujeme, že skutočné úlohy sa vykonávajú pomocou samostatnej úlohy ExecutorService s vyhradeným fondom vlákien.

5. Ukážka

Na záver je tu krátka ukážka plánovača:

private static int POOL_SIZE = 1; private static int QUEUE_SIZE = 10; @Test public void whenMultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked () {Job job1 = new Job ("Job1", JobPriority.LOW); Job job2 = new Job ("Job2", JobPriority.MEDIUM); Job job3 = new Job ("Job3", JobPriority.HIGH); Job job4 = new Job ("Job4", JobPriority.MEDIUM); Job job5 = new Job ("Job5", JobPriority.LOW); Job job6 = new Job ("Job6", JobPriority.HIGH); PriorityJobScheduler pjs = nový PriorityJobScheduler (POOL_SIZE, QUEUE_SIZE); pjs.scheduleJob (job1); pjs.scheduleJob (job2); pjs.scheduleJob (job3); pjs.scheduleJob (job4); pjs.scheduleJob (job5); pjs.scheduleJob (job6); // vyčistiť }

Aby sme predviedli, že úlohy sú vykonávané v poradí podľa priority, ponechali sme si POOL_SIZE ako 1, aj keď QUEUE_SIZE je 10. Poskytujeme úlohy s rôznou prioritou plánovaču.

Tu je ukážkový výstup, ktorý sme dostali pre jeden z cyklov:

Práca: Job3 Priorita: VYSOKÁ Job: Job6 Priorita: VYSOKÁ Job: Job4 Priorita: STREDNÁ Job: Job2 Priorita: STREDNÁ Job: Job1 Priorita: LOW Job: Job5 Priorita: LOW

Výstup sa môže v jednotlivých behoch líšiť. Nikdy by sme však nemali mať prípad, keď sa úloha s nižšou prioritou vykoná, aj keď front obsahuje úlohu s vyššou prioritou.

6. Záver

V tomto rýchlom návode sme videli, ako na to Priorita blokovania možno použiť na vykonávanie úloh vo vlastnom poradí priorít.

Ako obvykle, zdrojové súbory nájdete na GitHub.


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