A collection of Java concurrency simulations demonstrating thread pools, blocking queues, atomic variables, and scheduled executors through real-world scenarios.
src/
├── scenario1/ # Exam Submission Simulator
│ ├── ExamSubmissionSimulator.java
│ ├── NewSubmissionSystem.java
│ ├── OldSubmissionSystem.java
│ ├── Student.java
│ └── SubmissionStats.java
│
└── scenario2/ # Hospital Patient Flow Simulation
├── Main.java
├── Constants.java
├── Specialty.java
├── ShiftType.java
├── Patient.java
├── Consultant.java
├── PatientDispatcher.java
├── PatientArrivalSimulator.java
├── ConsultantWorker.java
├── ShiftManager.java
├── MetricsCollector.java
├── MetricsSnapshot.java
└── MetricsReporter.java
A discrete-event simulation of a hospital A&E department where patients arrive randomly, are triaged into specialty queues, and treated by consultant teams that rotate between day and night shifts. The simulation tracks key performance indicators such as the percentage of patients treated within a 4-hour waiting target.
| Entity | Description |
|---|---|
Patient |
Arrives with a random Specialty and a timestamped arrival time. |
Consultant |
Belongs to a Specialty and a ShiftType (DAY or NIGHT). |
Specialty |
One of PAEDIATRICS, SURGERY, or CARDIOLOGY. |
ShiftType |
DAY or NIGHT — each shift maps to a fixed team of 3 consultants. |
flowchart LR
subgraph arrivals [Patient Arrivals]
PAS["PatientArrivalSimulator"]
end
subgraph dispatch [Triage Dispatcher]
PD["PatientDispatcher"]
Q1["Queue: Paediatrics"]
Q2["Queue: Surgery"]
Q3["Queue: Cardiology"]
PD --> Q1
PD --> Q2
PD --> Q3
end
subgraph workers [Consultant Workers]
CW1["ConsultantWorker 1"]
CW2["ConsultantWorker 2"]
CW3["ConsultantWorker 3"]
end
subgraph management [Coordination]
SM["ShiftManager"]
MC["MetricsCollector"]
MR["MetricsReporter"]
end
PAS -->|"enqueue(patient)"| PD
Q1 -->|"poll()"| CW1
Q2 -->|"poll()"| CW2
Q3 -->|"poll()"| CW3
CW1 --> MC
CW2 --> MC
CW3 --> MC
SM -->|"epoch++ and submit new team"| workers
MC --> MR
-
PatientArrivalSimulatorschedules patient arrivals at random intervals on aScheduledExecutorService. Each patient is assigned a random specialty and placed into the correspondingBlockingQueuevia thePatientDispatcher. -
ShiftManagerkicks off the initial day shift by submitting threeConsultantWorkertasks (one per specialty) to a fixed thread pool. Every shift period, it increments a sharedshiftEpoch, swaps the active team (DAY/NIGHT), and submits the new team's workers. -
ConsultantWorkerpolls its specialty queue with a timeout. When a patient is dequeued, the worker simulates treatment viaThread.sleepand records metrics. The worker exits gracefully when it detects theshiftEpochhas changed, meaning its shift is over. -
MetricsCollectoraggregates statistics usingLongAddercounters.MetricsReporterprints periodic status snapshots and a final summary on shutdown.
Shift transitions are lock-free. The ShiftManager increments a shared AtomicInteger (the epoch) and immediately submits the incoming team. Each running ConsultantWorker captured its epoch at startup and checks it on every loop iteration and after each treatment. Once the epoch no longer matches, the worker finishes its current patient (if any) and exits. This allows old and new shift workers to briefly overlap without explicit synchronization.
Configured in Constants.java:
| Parameter | Value | Meaning |
|---|---|---|
SHIFT_DURATION_MS |
60,000 ms | 1 real minute = 12 simulated hospital hours |
FOUR_HOURS_SIM_MS |
20,000 ms | 4-hour wait KPI threshold (1/3 of a shift) |
TREATMENT_MIN_MS / MAX |
500 – 2,500 ms | Random treatment duration per patient |
ARRIVAL_MIN_MS / MAX |
200 – 1,200 ms | Random inter-arrival delay |
SIMULATION_RUN_MS |
180,000 ms | Total run time (3 minutes) |
REPORT_EVERY_MS |
5,000 ms | Periodic metrics report interval |
| Mechanism | Class | Role |
|---|---|---|
LinkedBlockingQueue |
PatientDispatcher |
One unbounded queue per specialty; thread-safe producer/consumer hand-off between arrivals and workers. |
ExecutorService (fixed pool of 3) |
Main |
Runs ConsultantWorker tasks — one thread per active consultant. |
ScheduledExecutorService (pool of 2) |
Main |
Schedules patient arrivals, shift rotations, and periodic metric reports. |
AtomicInteger (shift epoch) |
Main, ShiftManager, ConsultantWorker |
Lock-free epoch counter for coordinating shift handoffs without blocking. |
AtomicReference<ShiftType> |
Main, ShiftManager |
Shared current-shift indicator for reporting. |
LongAdder |
MetricsCollector |
High-throughput, lock-free metric counters under concurrent updates. |
volatile boolean |
PatientArrivalSimulator |
Stop flag for graceful shutdown of the arrival chain. |
- Total patients arrived and treated
- 4-hour wait target breaches and compliance percentage
- Average wait time (arrival to treatment start)
- Per-specialty: patients treated and maximum queue depth
- Current queue sizes at each reporting interval
A multithreaded exam submission system that processes 100,000 student submissions concurrently using an ExecutorService with a pool size scaled to available CPU cores. Uses CountDownLatch for synchronization, AtomicInteger/AtomicLong for lock-free statistics, and ThreadLocalRandom for thread-safe randomness.
Requirements: Java 21+ (uses instance main() method without static)
# Hospital Simulation (Scenario 2)
javac -d out src/scenario2/*.java
# Exam Submission Simulator (Scenario 1)
javac -d out src/scenario1/*.java# Hospital Simulation
java --enable-preview -cp out scenario2.Main
# Exam Submission Simulator
java --enable-preview -cp out scenario1.ExamSubmissionSimulatorNote: The
--enable-previewflag may be required depending on your JDK version, as the instancemain()method (withoutpublic static) was a preview feature before becoming standard.