Java: simulating round-robin CPU scheduling

Rotate jobs through a ready queue with a fixed time slice and record when each one finishes.

Java
import java.util.*;

class Main {
  public static void main(String[] args) {
    String[] names = {"A", "B", "C"};
    int[] remaining = {5, 3, 4};
    int quantum = 2;
    Deque<Integer> ready = new ArrayDeque<>(List.of(0, 1, 2));
    int clock = 0;
    while (!ready.isEmpty()) {
      int p = ready.pollFirst();
      int run = Math.min(quantum, remaining[p]);
      clock += run;
      remaining[p] -= run;
      System.out.println("t=" + clock + " ran " + names[p] + " for " + run);
      if (remaining[p] > 0) {
        ready.addLast(p);
      } else {
        System.out.println(names[p] + " finished at " + clock);
      }
    }
  }
}
Output
t=2 ran A for 2
t=4 ran B for 2
t=6 ran C for 2
t=8 ran A for 2
t=9 ran B for 1
B finished at 9
t=11 ran C for 2
C finished at 11
t=12 ran A for 1
A finished at 12

Explanation

Round-robin scheduling gives each ready process a fixed time slice called the quantum. A process that has not finished is moved to the back of the ready queue, so no job can hold the CPU for long and every job keeps getting turns.

The simulation keeps a queue of process indexes. It takes the first process, runs it for the smaller of the quantum and its remaining time, advances the clock, and either requeues it or reports that it finished. A smaller quantum improves responsiveness but increases the number of context switches.

Explore the dry run
Guided walkthroughReady
1import java.util.*;
2
3class Main {
4 public static void main(String[] args) {
5 String[] names = {"A", "B", "C"};
6 int[] remaining = {5, 3, 4};
7 int quantum = 2;
8 Deque<Integer> ready = new ArrayDeque<>(List.of(0, 1, 2));
9 int clock = 0;
10 while (!ready.isEmpty()) {
11 int p = ready.pollFirst();
12 int run = Math.min(quantum, remaining[p]);
13 clock += run;
14 remaining[p] -= run;
15 System.out.println("t=" + clock + " ran " + names[p] + " for " + run);
16 if (remaining[p] > 0) {
17 ready.addLast(p);
18 } else {
19 System.out.println(names[p] + " finished at " + clock);
20 }
21 }
22 }
23}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
All three jobs are ready at time 0, in the order A, B, C.queue = A, B, C
—
A job runs for a full quantum or less if it needs less.A: run = 2
—
An unfinished job goes to the back of the queue.queue = B, C, A after the first slice
—
B finishes at 9, C at 11, and A at 12.completion times: B=9, C=11, A=12
t=2 ran A for 2
t=4 ran B for 2
t=6 ran C for 2
t=8 ran A for 2
t=9 ran B for 1
B finished at 9
t=11 ran C for 2
C finished at 11
t=12 ran A for 1
A finished at 12

Cost and common mistakes

Each time slice costs O(1); the number of slices is the sum over jobs of ceil(burst / quantum).

  • A very large quantum makes round-robin behave like first-come, first-served. A very small one wastes time on context switches.
  • This model ignores the cost of a context switch and assumes every job arrives at time 0.

Try it yourself

How many slices does the schedule use?

Reveal answer and reasoning

Seven slices: A uses 3, B uses 2, and C uses 2.

Further reading