Prioritás alapú munkaütemezés Java-ban

1. Bemutatkozás

Többszálas környezetben néha egyedi kritériumok alapján kell ütemeznünk a feladatokat, nem csak a létrehozási idő helyett.

Lássuk, hogyan érhetjük el ezt a Java-ban - az a használatával PriorityBlockingQueue.

2. Áttekintés

Tegyük fel, hogy vannak olyan munkáink, amelyeket prioritásuk alapján szeretnénk elvégezni:

public class Állás megvalósítja Runnable {private String jobName; private JobPriority jobPriority; @Orride public void run () {System.out.println ("Munka:" + jobNév + "Prioritás:" + jobPriority); Szál.alszik (1000); // a tényleges végrehajtási idő szimulálására} // standard beállítók és getterek}

Bemutató célokra kinyomtatjuk a munkanevet és az elsőbbséget a fuss() módszer.

Mi is hozzátettük alvás() hogy hosszabb ideig futó munkát szimuláljunk; a feladat végrehajtása közben több feladat halmozódik fel a prioritási sorban.

Végül, JobPriority egyszerű leírás:

public enum JobPriority {HIGH, MEDIUM, LOW}

3. Egyedi Összehasonlító

Írnunk kell egy összehasonlítót, amely meghatározza az egyéni kritériumokat; és Java 8-ban ez triviális:

Comparator.comparing (Job :: getJobPriority);

4. Kiemelt munkaütemező

Az összes beállítással végezzük el most egy egyszerű munkaütemezőt - amely egyetlen szál végrehajtót alkalmaz, hogy munkát kereshessen a PriorityBlockingQueue és végrehajtja őket:

public class PriorityJobScheduler {private ExecutorService priorityJobPoolExecutor; private ExecutorService priorityJobScheduler = Executors.newSingleThreadExecutor (); privát PriorityBlockingQueueQueue; public PriorityJobScheduler (Integer poolSize, Integer queueSize) {priorJobPoolExecutor = Executors.newFixedThreadPool (poolSize); priorityQueue = új PriorityBlockingQueue (queueSize, Comparator.comparing (Job :: getJobPriority)); priorityJobScheduler.execute (() -> {while (true) {try {priorityJobPoolExecutor.execute (priorityQueue.take ());} catch (InterruptedException e) {// kivétel speciális kezelési szünetet igényel;}}}); } public void scheduleJob (Munkahelyi munka) {priorityQueue.add (job); }}

A legfontosabb itt egy példány létrehozása PriorityBlockingQueue nak,-nek Munka gépeljen be egyéni összehasonlítóval. A következő végrehajtandó feladatot a sor választja ki a használatával vesz() módszer, amely lekéri és eltávolítja a sor fejét.

Az ügyfél kódjának most egyszerűen meg kell hívnia a scheduleJob () - ami hozzáadja az állást a sorhoz. A priorityQueue.add () megfelelő sorba állítja az állást a sorban lévő meglévő munkahelyekhez képest, a JobExecutionComparator.

Ne feledje, hogy a tényleges feladatokat külön külön hajtják végre ExecutorService dedikált szálmedencével.

5. Demo

Végül íme az ütemező gyors bemutatása:

privát statikus int POOL_SIZE = 1; privát statikus 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 = új munka ("Job5", JobPriority.LOW); Job job6 = új állás ("Job6", JobPriority.HIGH); PriorityJobScheduler pjs = új PriorityJobScheduler (POOL_SIZE, QUEUE_SIZE); pjs.scheduleJob (job1); pjs.scheduleJob (job2); pjs.scheduleJob (job3); pjs.scheduleJob (job4); pjs.scheduleJob (job5); pjs.scheduleJob (job6); // takarítás}

Annak bemutatására, hogy a munkákat prioritási sorrendben hajtják végre, megtartottuk a POOL_SIZE mint 1 annak ellenére, hogy a QUEUE_SIZE a 10. Változó prioritású munkákat biztosítunk az ütemező számára.

Itt van egy minta kimenet, amelyet az egyik futáshoz kaptunk:

Munka: Munka3 Prioritás: MAGAS Munka: Munka6 Prioritás: MAGAS Munka: Munka4 Prioritás: KÖZEPES Munka: Munka2 Prioritás: KÖZEPES Munka: Munka1 Prioritás: LOW Munka: Munka5 Prioritás: LOW

A kimenet futásonként változhat. Soha nem fordulhat elő olyan eset, amikor alacsonyabb prioritású munkát hajtanak végre akkor is, ha a sor magasabb prioritású munkát tartalmaz.

6. Következtetés

Ebben a gyors bemutatóban láttuk, hogyan PriorityBlockingQueue használható feladatok egyéni prioritási sorrendben történő végrehajtására.

Szokás szerint a forrásfájlok megtalálhatók a GitHubon.