Prioritetsbaseret jobplanlægning i Java

1. Introduktion

I et miljø med flere tråde er vi undertiden nødt til at planlægge opgaver baseret på brugerdefinerede kriterier i stedet for kun oprettelsestiden.

Lad os se, hvordan vi kan opnå dette i Java - ved hjælp af en PriorityBlockingQueue.

2. Oversigt

Lad os sige, at vi har job, som vi vil udføre på baggrund af deres prioritet:

offentlig klasse Job implementerer Runnable {private String jobName; privat JobPrioritet jobPrioritet; @Override public void run () {System.out.println ("Job:" + jobName + "Priority:" + jobPriority); Tråd. Søvn (1000); // for at simulere faktisk udførelsestid} // standard settere og getters}

Af demonstrationsformål udskriver vi jobnavnet og prioriteten i løb() metode.

Vi tilføjede også søvn() så vi simulerer et længerevarende job; mens jobbet udføres, akkumuleres flere job i prioritetskøen.

Langt om længe, JobPrioritet er en simpel enum:

offentlig enum JobPriority {HIGH, MEDIUM, LOW}

3. Brugerdefineret Komparator

Vi er nødt til at skrive en komparator, der definerer vores brugerdefinerede kriterier; og i Java 8 er det trivielt:

Comparator.comparing (Job :: getJobPriority);

4. Prioriteret jobplanlægning

Når alt opsætningen er udført, lad os nu implementere en simpel jobplanlægning - som anvender en enkelt trådudførelse til at lede efter job i PriorityBlockingQueue og udfører dem:

offentlig klasse PriorityJobScheduler {private ExecutorService prioritetJobPoolExecutor; private ExecutorService-prioritetJobScheduler = Executors.newSingleThreadExecutor (); privat PriorityBlockingQueue prioritetQueue; public PriorityJobScheduler (Integer poolSize, Integer queueSize) {priorityJobPoolExecutor = Executors.newFixedThreadPool (poolSize); PriorityQueue = ny PriorityBlockingQueue (queueSize, Comparator.comparing (Job :: getJobPriority)); prioritetJobScheduler.execute (() -> {mens (sand) {prøv {prioritetJobPoolExecutor.execute (prioritetQueue.take ());} fangst (InterruptedException e) {// undtagelse kræver særlig håndteringspause;}}}); } offentlig ugyldig tidsplanJob (jobjob) {prioritetQueue.add (job); }}

Nøglen her er at oprette en forekomst af PriorityBlockingQueue af Job skriv med en brugerdefineret komparator. Det næste job, der skal udføres, vælges fra køen ved hjælp af tage() metode, der henter og fjerner hovedet på køen.

Klientkoden skal nu blot ringe til tidsplanJob () - som tilføjer jobbet til køen. Det PriorityQueue.add () køer jobbet i passende position sammenlignet med eksisterende job i køen ved hjælp af JobExecutionComparator.

Bemærk, at de aktuelle job udføres ved hjælp af en separat ExecutorService med en dedikeret trådpulje.

5. Demo

Endelig er her en hurtig demonstration af planlæggeren:

privat statisk int POOL_SIZE = 1; privat statisk int QUEUE_SIZE = 10; @Test offentligt ugyldigt nårMultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked () {Job job1 = nyt job ("Job1", JobPriority.LOW); Job job2 = nyt job ("Job2", JobPriority.MEDIUM); Job job3 = nyt job ("Job3", JobPriority.HIGH); Job job4 = nyt job ("Job4", JobPriority.MEDIUM); Job job5 = nyt job ("Job5", JobPriority.LOW); Job job6 = nyt job ("Job6", JobPriority.HIGH); PriorityJobScheduler pjs = ny PriorityJobScheduler (POOL_SIZE, QUEUE_SIZE); pjs.scheduleJob (job1); pjs.scheduleJob (job2); pjs.scheduleJob (job3); pjs.scheduleJob (job4); pjs.scheduleJob (job5); pjs.scheduleJob (job6); // Ryd op }

For at demonstrere, at jobene udføres i prioritetsrækkefølgen, har vi holdt POOL_SIZE som 1, selvom QUEUE_SIZE er 10. Vi leverer job med varierende prioritet til planlæggeren.

Her er en prøveudgang, vi fik til en af ​​kørslerne:

Job: Job3 Prioritet: HIGH Job: Job6 Prioritet: HIGH Job: Job4 Prioritet: MEDIUM Job: Job2 Prioritet: MEDIUM Job: Job1 Prioritet: LAV Job: Job5 Prioritet: LAV

Outputtet kan variere på tværs af kørsler. Vi bør dog aldrig have et tilfælde, hvor et job med lavere prioritet udføres, selv når køen indeholder et job med højere prioritet.

6. Konklusion

I denne hurtige vejledning så vi hvordan PriorityBlockingQueue kan bruges til at udføre job i en brugerdefineret prioritetsrækkefølge.

Som normalt kan kildefiler findes på GitHub.


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