mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-15 22:15:02 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d741df1e3a | ||
|
|
3b46af6190 | ||
|
|
d9512df57b | ||
|
|
cd0c4db685 |
No files matched your search
@@ -210,6 +210,7 @@
|
||||
<module>crtp</module>
|
||||
<module>log-aggregation</module>
|
||||
<module>health-check</module>
|
||||
<module>scheduler</module>
|
||||
</modules>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: Scheduler Pattern
|
||||
category: Creational
|
||||
language: en
|
||||
tag:
|
||||
- Generic
|
||||
---
|
||||
|
||||
## Name
|
||||
Scheduler Design Pattern
|
||||
|
||||
## Intent
|
||||
The Scheduler Design Pattern is used to manage and coordinate the execution of tasks or jobs in a system. It provides a mechanism for scheduling and executing tasks at specific times, intervals, or in response to certain events. This pattern is especially useful when dealing with asynchronous operations, background processing, and resource allocation.
|
||||
|
||||
## Explanation
|
||||
|
||||
### Real-world example
|
||||
> Think of a restaurant kitchen with various dishes to be prepared – the chef is like a scheduler who ensures that each dish is cooked at the right time and served to customers without letting the kitchen become chaotic or the food getting cold.
|
||||
|
||||
### In plain words
|
||||
> The Scheduler Design Pattern ensures your tasks get done at the right time and order.
|
||||
|
||||
### Wikipedia says
|
||||
> In computing, scheduling is the action of assigning resources to perform tasks. The resources may be processors, network links or expansion cards. The tasks may be threads, processes or data flows.
|
||||
|
||||
> The scheduling activity is carried out by a process called scheduler. Schedulers are often designed so as to keep all computer resources busy (as in load balancing), allow multiple users to share system resources effectively, or to achieve a target quality-of-service.
|
||||
|
||||
> Scheduling is fundamental to computation itself, and an intrinsic part of the execution model of a computer system; the concept of scheduling makes it possible to have computer multitasking with a single central processing unit (CPU).
|
||||
|
||||
### Programmatic example
|
||||
In our demo, we will have a class `Task` with following attributes:
|
||||
```java
|
||||
public class Task {
|
||||
int id;
|
||||
int totalExecutionTime;
|
||||
int priority = 0;
|
||||
}
|
||||
```
|
||||
And a `Scheduler` class which will be responsible for scheduling the tasks:
|
||||
```java
|
||||
public interface TaskScheduler {
|
||||
void scheduleTask(Task task);
|
||||
}
|
||||
```
|
||||
Base on the strategy of the scheduler, we can have different implementations of `TaskScheduler` interface. For example, a `PriorityScheduler` which will schedule the tasks based on their priority:
|
||||
```java
|
||||
public class PriorityScheduler implements TaskScheduler {
|
||||
private final Queue<Task> taskQueue =
|
||||
new PriorityQueue<>(
|
||||
(task1, task2) -> {
|
||||
if (task2.priority != task1.priority) {
|
||||
return task2.priority - task1.priority;
|
||||
}
|
||||
return task1.id - task2.id;
|
||||
});
|
||||
|
||||
@Override
|
||||
public void scheduleTask(Task task) {
|
||||
taskQueue.add(task);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
The Scheduler Design Pattern is applicable in various scenarios, including but not limited to:
|
||||
|
||||
- **Task Queue Management**: When you need to manage a queue of tasks to be executed, ensuring tasks are executed in a specific order, on specific resources, or with certain priorities.
|
||||
|
||||
- **Background Processing**: In applications requiring background jobs, such as processing user requests asynchronously, sending emails, or performing periodic maintenance tasks.
|
||||
|
||||
- **Resource Allocation**: For managing shared resources, like database connections or thread pools, to ensure fair allocation among competing tasks.
|
||||
|
||||
- **Real-time Systems**: In systems where tasks need to be executed at precise times or in response to specific events, such as in real-time simulations or monitoring systems.
|
||||
|
||||
## Known uses
|
||||
The Scheduler Design Pattern is used in various software applications and frameworks, including:
|
||||
|
||||
- Operating systems for managing processes.
|
||||
- Java: The Java `ScheduledExecutorService` class is an implementation of the Scheduler Design Pattern, allowing the scheduling of tasks at fixed rate or with fixed delay.
|
||||
|
||||
## Consequences
|
||||
The Scheduler Design Pattern offers several advantages:
|
||||
- **Flexibility**: It allows for dynamic scheduling of tasks, making it adaptable to changing requirements.
|
||||
- **Efficiency**: Tasks can be optimized for resource utilization, and parallel execution can be managed effectively.
|
||||
- **Maintainability**: Separating scheduling logic from task execution simplifies maintenance and debugging.
|
||||
|
||||
However, it also has some potential drawbacks:
|
||||
- **Complexity**: Implementing a scheduler can be complex, especially in systems with intricate scheduling requirements.
|
||||
- **Overhead**: Maintaining a scheduler adds some overhead to the system.
|
||||
|
||||
|
||||
## Related patterns
|
||||
The Scheduler Design Pattern is related to other design patterns, including:
|
||||
- **Observer Pattern**: When tasks need to be scheduled in response to specific events or changes in the system, the Observer Pattern can be used in conjunction with the Scheduler Pattern.
|
||||
- **Command Pattern**: Tasks to be executed by the scheduler can often be encapsulated using the Command Pattern, allowing for easy parameterization and queuing.
|
||||
|
||||
## Credits
|
||||
- [Wikipedia: Scheduling (computing)](https://en.wikipedia.org/wiki/Scheduling_(computing))
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
@@ -0,0 +1,41 @@
|
||||
@startuml
|
||||
|
||||
class Task {
|
||||
-id: int
|
||||
-totalExecutionTime: int
|
||||
-priority: int
|
||||
--
|
||||
+Task(id: int, totalExecutionTime: int, priority: int)
|
||||
+Task(id: int, totalExecutionTime: int)
|
||||
+getId(): int
|
||||
+getTotalExecutionTime(): int
|
||||
+getPriority(): int
|
||||
}
|
||||
|
||||
interface TaskScheduler {
|
||||
+scheduleTask(task: Task): void
|
||||
+update(int deltaTime): void
|
||||
}
|
||||
|
||||
class FirstComeFirstServedScheduler extends TaskScheduler {}
|
||||
class PriorityScheduler extends TaskScheduler {}
|
||||
class RoundRobinScheduler extends TaskScheduler {}
|
||||
class ShortestRemainingTimeFirstScheduler extends TaskScheduler {}
|
||||
|
||||
class Simulator {
|
||||
-scheduler: TaskScheduler
|
||||
-Map<Integer, List<Task>> tasks
|
||||
-deltaTime: int
|
||||
-simulateTime: int
|
||||
-LinkedHashMap<Integer, Integer> taskCompletedOrder
|
||||
-elapsedTime: int
|
||||
--
|
||||
+Simulator(scheduler: TaskScheduler, tasks: Map<Integer, List<Task>>, deltaTime: int, simulateTime: int)
|
||||
+simulate(): LinkedHashMap<Integer, Integer>
|
||||
}
|
||||
|
||||
Task -- TaskScheduler : "1..*"
|
||||
TaskScheduler -- Simulator : "1"
|
||||
Simulator ..> Task : "1..*"
|
||||
|
||||
@enduml
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.26.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>scheduler</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/**Tasks are scheduled in the order they arrive. */
|
||||
public class FirstComeFirstServedScheduler implements TaskScheduler, PropertyChangeListener {
|
||||
private final Queue<Task> taskQueue = new LinkedList<>();
|
||||
|
||||
@Override
|
||||
public void scheduleTask(Task task) {
|
||||
task.getSupport().addPropertyChangeListener(this);
|
||||
taskQueue.add(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int deltaTime) {
|
||||
Task task = taskQueue.peek();
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
task.execute(deltaTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (Task.COMPLETE_PROPERTY.equals(evt.getPropertyName())) {
|
||||
onTaskComplete(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void onTaskComplete(PropertyChangeEvent evt) {
|
||||
Task task = (Task) evt.getSource();
|
||||
taskQueue.remove(task);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3), new Task(2, 2), new Task(3, 4)));
|
||||
|
||||
TaskScheduler scheduler = new FirstComeFirstServedScheduler();
|
||||
Simulator simulator = new Simulator(scheduler, tasks, 1, 100);
|
||||
simulator.simulate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
|
||||
/** Tasks with higher priority values are executed before tasks with lower priority values. */
|
||||
public class PriorityScheduler implements TaskScheduler, PropertyChangeListener {
|
||||
private final Queue<Task> taskQueue =
|
||||
new PriorityQueue<>(
|
||||
(task1, task2) -> {
|
||||
if (task2.getPriority() != task1.getPriority()) {
|
||||
return task2.getPriority() - task1.getPriority();
|
||||
}
|
||||
return task1.getId() - task2.getId(); // lower id (earlier task) has higher priority
|
||||
});
|
||||
|
||||
@Override
|
||||
public void scheduleTask(Task task) {
|
||||
task.getSupport().addPropertyChangeListener(this);
|
||||
taskQueue.add(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int deltaTime) {
|
||||
Task task = taskQueue.peek();
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
task.execute(deltaTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (Task.COMPLETE_PROPERTY.equals(evt.getPropertyName())) {
|
||||
onTaskComplete(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void onTaskComplete(PropertyChangeEvent evt) {
|
||||
Task task = (Task) evt.getSource();
|
||||
taskQueue.remove(task);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* Round Robin technique. Tasks are executed in a cyclic order, with each task getting a fixed time
|
||||
* quantum for execution.
|
||||
*/
|
||||
public class RoundRobinScheduler implements TaskScheduler {
|
||||
private final Queue<Task> taskQueue = new LinkedList<>();
|
||||
|
||||
@Override
|
||||
public void scheduleTask(Task task) {
|
||||
taskQueue.add(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int deltaTime) {
|
||||
Task task = taskQueue.poll();
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
task.execute(deltaTime);
|
||||
if (!task.isComplete()) {
|
||||
taskQueue.add(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
|
||||
/** The task with the shortest remaining execution time is given priority. */
|
||||
public class ShortestRemainingTimeFirstScheduler implements TaskScheduler {
|
||||
private final Queue<Task> taskQueue =
|
||||
new PriorityQueue<>(
|
||||
(task1, task2) -> {
|
||||
if (task2.getRemainingTime() != task1.getRemainingTime()) {
|
||||
return task1.getRemainingTime() - task2.getRemainingTime();
|
||||
}
|
||||
return task1.getId() - task2.getId(); // lower id (earlier task) has higher priority
|
||||
});
|
||||
|
||||
@Override
|
||||
public void scheduleTask(Task task) {
|
||||
taskQueue.add(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int deltaTime) {
|
||||
Task task = taskQueue.poll();
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
task.execute(deltaTime);
|
||||
if (!task.isComplete()) {
|
||||
taskQueue.add(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/** Simulate scheduler schedule tasks. */
|
||||
@RequiredArgsConstructor
|
||||
public class Simulator implements PropertyChangeListener {
|
||||
private final TaskScheduler scheduler;
|
||||
|
||||
/** Map time to tasks that need to be scheduled at that time. */
|
||||
private final Map<Integer, List<Task>> tasks;
|
||||
|
||||
private final int deltaTime;
|
||||
private final int simulateTime;
|
||||
private final LinkedHashMap<Integer, Integer> taskCompletedOrder = new LinkedHashMap<>();
|
||||
private int elapsedTime = 0;
|
||||
|
||||
/**
|
||||
* Simulate scheduler schedule tasks, then return a LinkedHashMap present the completed order of
|
||||
* tasks, which map task id to the time it completed.
|
||||
*/
|
||||
public Map<Integer, Integer> simulate() {
|
||||
while (elapsedTime < simulateTime) {
|
||||
if (tasks.containsKey(elapsedTime)) {
|
||||
for (Task task : tasks.get(elapsedTime)) {
|
||||
task.getSupport().addPropertyChangeListener(this);
|
||||
scheduler.scheduleTask(task);
|
||||
}
|
||||
}
|
||||
scheduler.update(deltaTime);
|
||||
elapsedTime += deltaTime;
|
||||
}
|
||||
return taskCompletedOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (Task.COMPLETE_PROPERTY.equals(evt.getPropertyName())) {
|
||||
onTaskComplete(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void onTaskComplete(PropertyChangeEvent evt) {
|
||||
Task task = (Task) evt.getSource();
|
||||
/*
|
||||
elapsedTime is updated after task dispatch complete event to simulator,
|
||||
so we need to add deltaTime
|
||||
*/
|
||||
taskCompletedOrder.put(task.getId(), elapsedTime + deltaTime);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/** Task that need to be scheduled. */
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class Task {
|
||||
public static final String COMPLETE_PROPERTY = "complete";
|
||||
private final PropertyChangeSupport support = new PropertyChangeSupport(this);
|
||||
private final int id;
|
||||
private final int totalExecutionTime;
|
||||
|
||||
/** The priority of the task. The higher the number, the higher the priority. */
|
||||
private int priority = 0;
|
||||
|
||||
/** The time that the task run. */
|
||||
private int elapsedTime = 0;
|
||||
|
||||
/** Whether the task is completed. */
|
||||
private boolean complete = false;
|
||||
|
||||
/** Create a task with id, total execution time and priority. */
|
||||
public Task(int id, int totalExecutionTime, int priority) {
|
||||
this.id = id;
|
||||
this.totalExecutionTime = totalExecutionTime;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
/** Execute the task for a given number of seconds. */
|
||||
public void execute(int seconds) {
|
||||
if (complete) {
|
||||
throw new IllegalStateException("Task already completed");
|
||||
}
|
||||
|
||||
elapsedTime += seconds;
|
||||
|
||||
logTaskProgress();
|
||||
|
||||
if (elapsedTime >= totalExecutionTime) {
|
||||
complete = true;
|
||||
support.firePropertyChange(COMPLETE_PROPERTY, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void logTaskProgress() {
|
||||
LOGGER.info("Task {} is {}/{} complete\n", id, elapsedTime, totalExecutionTime);
|
||||
}
|
||||
|
||||
public int getRemainingTime() {
|
||||
return totalExecutionTime - elapsedTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
/** The scheduler is responsible for scheduling tasks. */
|
||||
public interface TaskScheduler {
|
||||
/** Add task to the scheduler. */
|
||||
void scheduleTask(Task task);
|
||||
|
||||
/** Update to execute scheduled tasks. */
|
||||
void update(int deltaTime);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class FirstComeFirstServedSchedulerTest {
|
||||
@Test
|
||||
void testExecuteTasksFromBeginning() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3), new Task(2, 2), new Task(3, 4)));
|
||||
|
||||
Simulator simulator = new Simulator(new FirstComeFirstServedScheduler(), tasks, 1, 100);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
|
||||
assertEquals(3, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(1, 2, 3), taskCompletedOrder.keySet());
|
||||
assertEquals(3, taskCompletedOrder.get(1));
|
||||
assertEquals(5, taskCompletedOrder.get(2));
|
||||
assertEquals(9, taskCompletedOrder.get(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteTasks() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3)));
|
||||
tasks.put(1, List.of(new Task(2, 2)));
|
||||
tasks.put(6, List.of(new Task(3, 4)));
|
||||
tasks.put(7, List.of(new Task(4, 2)));
|
||||
tasks.put(8, List.of(new Task(5, 1)));
|
||||
|
||||
Simulator simulator = new Simulator(new FirstComeFirstServedScheduler(), tasks, 1, 100);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
|
||||
assertEquals(5, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(1, 2, 3, 4, 5), taskCompletedOrder.keySet());
|
||||
assertEquals(3, taskCompletedOrder.get(1));
|
||||
assertEquals(5, taskCompletedOrder.get(2));
|
||||
assertEquals(10, taskCompletedOrder.get(3));
|
||||
assertEquals(12, taskCompletedOrder.get(4));
|
||||
assertEquals(13, taskCompletedOrder.get(5));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class PrioritySchedulerTest {
|
||||
@Test
|
||||
void testExecuteTasksFromBeginning() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3, 0), new Task(2, 2, 2), new Task(3, 1, 1)));
|
||||
|
||||
Simulator simulator = new Simulator(new PriorityScheduler(), tasks, 1, 10);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
|
||||
assertEquals(3, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(2, 3, 1), taskCompletedOrder.keySet());
|
||||
assertEquals(2, taskCompletedOrder.get(2));
|
||||
assertEquals(3, taskCompletedOrder.get(3));
|
||||
assertEquals(6, taskCompletedOrder.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteTasks() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3, 1)));
|
||||
tasks.put(1, List.of(new Task(2, 2, 0)));
|
||||
tasks.put(2, List.of(new Task(3, 4, 5)));
|
||||
tasks.put(7, List.of(new Task(4, 2, 4)));
|
||||
tasks.put(8, List.of(new Task(5, 1, 2)));
|
||||
|
||||
Simulator simulator = new Simulator(new PriorityScheduler(), tasks, 1, 100);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
|
||||
assertEquals(5, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(3, 1, 4, 5, 2), taskCompletedOrder.keySet());
|
||||
assertEquals(6, taskCompletedOrder.get(3));
|
||||
assertEquals(7, taskCompletedOrder.get(1));
|
||||
assertEquals(9, taskCompletedOrder.get(4));
|
||||
assertEquals(10, taskCompletedOrder.get(5));
|
||||
assertEquals(12, taskCompletedOrder.get(2));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class RoundRobinSchedulerTest {
|
||||
@Test
|
||||
void testExecuteTasksFromBeginning() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3), new Task(2, 2), new Task(3, 4)));
|
||||
|
||||
Simulator simulator = new Simulator(new RoundRobinScheduler(), tasks, 1, 10);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
assertEquals(3, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(2, 1, 3), taskCompletedOrder.keySet());
|
||||
assertEquals(5, taskCompletedOrder.get(2));
|
||||
assertEquals(7, taskCompletedOrder.get(1));
|
||||
assertEquals(9, taskCompletedOrder.get(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteTasks() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3)));
|
||||
tasks.put(1, List.of(new Task(2, 2)));
|
||||
tasks.put(2, List.of(new Task(3, 4)));
|
||||
tasks.put(7, List.of(new Task(4, 2)));
|
||||
tasks.put(8, List.of(new Task(5, 1)));
|
||||
|
||||
Simulator simulator = new Simulator(new RoundRobinScheduler(), tasks, 1, 100);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
|
||||
assertEquals(5, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(1, 2, 3, 5, 4), taskCompletedOrder.keySet());
|
||||
assertEquals(4, taskCompletedOrder.get(1));
|
||||
assertEquals(6, taskCompletedOrder.get(2));
|
||||
assertEquals(10, taskCompletedOrder.get(3));
|
||||
assertEquals(11, taskCompletedOrder.get(5));
|
||||
assertEquals(12, taskCompletedOrder.get(4));
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.iluwatar.scheduler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ShortestRemainingTimeFirstSchedulerTest {
|
||||
@Test
|
||||
void testExecuteTasksFromBeginning() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3), new Task(2, 2), new Task(3, 4)));
|
||||
|
||||
Simulator simulator = new Simulator(new ShortestRemainingTimeFirstScheduler(), tasks, 1, 10);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
assertEquals(3, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(2, 1, 3), taskCompletedOrder.keySet());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteTasks() {
|
||||
Map<Integer, List<Task>> tasks = new HashMap<>();
|
||||
tasks.put(0, List.of(new Task(1, 3)));
|
||||
tasks.put(1, List.of(new Task(2, 2)));
|
||||
tasks.put(2, List.of(new Task(3, 4)));
|
||||
tasks.put(7, List.of(new Task(4, 2)));
|
||||
tasks.put(8, List.of(new Task(5, 1)));
|
||||
|
||||
Simulator simulator = new Simulator(new ShortestRemainingTimeFirstScheduler(), tasks, 1, 100);
|
||||
|
||||
Map<Integer, Integer> taskCompletedOrder = simulator.simulate();
|
||||
|
||||
assertEquals(5, taskCompletedOrder.size());
|
||||
assertIterableEquals(List.of(1, 2, 3, 5, 4), taskCompletedOrder.keySet());
|
||||
assertEquals(3, taskCompletedOrder.get(1));
|
||||
assertEquals(5, taskCompletedOrder.get(2));
|
||||
assertEquals(9, taskCompletedOrder.get(3));
|
||||
assertEquals(10, taskCompletedOrder.get(5));
|
||||
assertEquals(12, taskCompletedOrder.get(4));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user