Raspored poslova zasnovan na prioritetu u Javi

1. Uvod

U okruženju s više niti, ponekad moramo rasporediti zadatke na temelju prilagođenih kriterija, umjesto samo na vremenu izrade.

Pogledajmo kako to možemo postići na Javi - pomoću a PriorityBlockingQueue.

2. Pregled

Recimo da imamo poslove koje želimo izvršavati na temelju njihovog prioriteta:

posao javne klase implementira Runnable {private String jobName; privatni JobPriority jobPriority; @Override public void run () {System.out.println ("Job:" + jobName + "Priority:" + jobPriority); Navoj.spavanje (1000); // za simulaciju stvarnog vremena izvršenja} // standardni postavljači i getteri}

U svrhu demonstracije ispisujemo naziv posla i prioritet u trčanje() metoda.

Također smo dodali spavati() tako da simuliramo posao koji traje duže; dok se posao izvršava, više poslova skupit će se u prioritetnom redu.

Konačno, Prioritet posla je jednostavan nabroj:

javni popis JobPriority {HIGH, MEDIUM, LOW}

3. Prilagođeno Usporednik

Moramo napisati usporedbu koja definira naše prilagođene kriterije; i u Javi 8 trivijalno:

Comparator.comparing (Job :: getJobPriority);

4. Planer prioriteta poslova

Nakon završetka postavljanja, implementirajmo jednostavan planer posla - koji zapošljava izvršitelja s jednom niti za traženje poslova u PriorityBlockingQueue i izvršava ih:

javna klasa PriorityJobScheduler {private ExecutorService priorityJobPoolExecutor; private ExecutorService prioritetJobScheduler = Izvršitelji.newSingleThreadExecutor (); private PriorityBlockingQueue priorityQueue; javni PriorityJobScheduler (Integer poolSize, Integer queueSize) {prioritetJobPoolExecutor = Izvršitelji.newFixedThreadPool (poolSize); priorityQueue = novi PriorityBlockingQueue (queueSize, Comparator.comparing (Job :: getJobPriority)); prioritetJobScheduler.execute (() -> {while (true) {try {priorityJobPoolExecutor.execute (prioritetQueue.take ());} catch (InterruptedException e) {// izuzetak treba posebnu pauzu rukovanja;}}}); } public void scheduleJob (posao posla) {prioritetQueue.add (posao); }}

Ključno je ovdje stvoriti instancu PriorityBlockingQueue od Posao tip s prilagođenim usporednikom. Sljedeći posao koji treba izvršiti odabire se iz reda pomoću uzeti() metoda koja dohvaća i uklanja glavu reda.

Klijentski kod sada jednostavno treba nazvati scheduleJob () - što dodaje posao u red čekanja. The prioritetQueue.add () postavlja posao na čekanje na odgovarajuću poziciju u odnosu na postojeće poslove u redu čekanja, koristeći JobExecutionComparator.

Imajte na umu da se stvarni poslovi izvršavaju pomoću zasebnog ExecutorService s namjenskim bazenom niti.

5. Demo

Na kraju, evo kratke demonstracije planera:

privatni statički int POOL_SIZE = 1; privatni statički int QUEUE_SIZE = 10; @Test public void whenMultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked () {Job job1 = new Job ("Job1", JobPriority.LOW); Posao posao2 = novi posao ("Posao2", JobPriority.MEDIUM); Job job3 = novi posao ("Job3", JobPriority.HIGH); Posao posao4 = novi posao ("Job4", JobPriority.MEDIUM); Posao5 = novi posao ("Posao5", JobPriority.LOW); Job job6 = novi posao ("Job6", JobPriority.HIGH); PriorityJobScheduler pjs = novi PriorityJobScheduler (POOL_SIZE, QUEUE_SIZE); pjs.scheduleJob (posao1); pjs.scheduleJob (posao2); pjs.scheduleJob (posao3); pjs.scheduleJob (posao4); pjs.scheduleJob (posao5); pjs.scheduleJob (posao6); // počistiti }

Kako bismo demonstrirali da se poslovi izvršavaju prema redoslijedu prioriteta, zadržali smo VELIČINA BAZENA kao 1 iako je QUEUE_SIZE je 10. Planerima pružamo poslove s različitim prioritetom.

Evo primjera rezultata koji smo dobili za jedno od izvođenja:

Posao: Job3 Prioritet: HIGH Posao: Job6 Prioritet: HIGH Posao: Job4 Prioritet: SREDNJI Posao: Job2 Prioritet: SREDNJI Posao: Job1 Prioritet: LOW

Izlaz se može razlikovati u različitim izvedbama. Međutim, nikada ne bismo trebali imati slučaj kada se izvršava posao nižeg prioriteta, čak i ako red sadrži posao višeg prioriteta.

6. Zaključak

U ovom smo brzom vodiču vidjeli kako PriorityBlockingQueue može se koristiti za izvršavanje poslova prilagođenim redoslijedom prioriteta.

Kao i obično, izvorne datoteke mogu se naći na GitHubu.


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