Skip to main content

Java simulation of single server queue

Short answer

A Java discrete-event simulation uses a priority queue for events, advancing clock to the next arrival or departure. It tracks server status and queue, updating statistics like average queue length and utilization. Example: exponential inter-arrival and service times, run for 1000 customers, output average delay, queue length, utilization.

Explain the structure of simulation in Java (single server queue model) with example.

A Java discrete-event simulation of a single-server queue (such as a bank with one teller) is built from a simulation clock, an event list, state variables, statistics and an event-driven main loop. The model is event-scheduling based: the clock jumps from one event to the next imminent event.

Structure

  1. Classes
    • Event: type (arrival or departure) and time. It implements Comparable so the earliest event comes first.
    • Sim (main class): clock, event list (a PriorityQueue<Event>), customer queue (a LinkedList), server status, statistics.
    • Random generators: java.util.Random with a seed, to produce exponential inter-arrival and service times.
  2. State variables: server busy (boolean), queue length, clock.
  3. Statistics: total delay, customers served, area under the queue-length curve, total busy time.
  4. Methods: initialize(), arrival(), departure(), report(), and the main loop.

Flow

initialize: clock=0, schedule 1st arrival
       |
  +--> take next event from list
  |    advance clock, update statistics
  |    arrival or departure? -> handle
  |    schedule new events
  +--- stop? no
       |yes
     report()

Example code

import java.util.*;
public class Sim {
  static double clock = 0, lastT = 0, busyT = 0, area = 0, delay = 0;
  static int served = 0; static boolean busy = false;
  static Random r = new Random(1);
  static PriorityQueue<double[]> fel =
      new PriorityQueue<>((a, b) -> Double.compare(a[0], b[0]));
  static LinkedList<Double> q = new LinkedList<>();
  static double expo(double m) { return -m * Math.log(1 - r.nextDouble()); }

  public static void main(String[] a) {
    fel.add(new double[]{expo(4), 0});       // type 0 = arrival
    while (served < 1000) {
      double[] e = fel.poll();
      area += q.size() * (e[0] - clock);
      if (busy) busyT += e[0] - clock;
      clock = e[0];
      if (e[1] == 0) {                       // arrival
        fel.add(new double[]{clock + expo(4), 0});
        if (busy) q.add(clock);
        else { busy = true; fel.add(new double[]{clock + expo(3), 1}); }
      } else {                               // departure
        served++;
        if (q.isEmpty()) busy = false;
        else { delay += clock - q.poll();
               fel.add(new double[]{clock + expo(3), 1}); }
      }
    }
    System.out.println("Avg delay " + delay / served);
    System.out.println("Avg queue " + area / clock);
    System.out.println("Utilisation " + busyT / clock);
  }
}

Here mean inter-arrival time is 4 and mean service time is 3 (time units), so theoretically utilisation is 0.75. The program stops after 1000 customers and prints average delay, average queue length and server utilisation.

✓ Answer checked by Claude Opus 5.5 (high effort)

All Simulation and Modeling chapter 9 questions →