Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ public static void main(String[] args) {
Job job5 = jobBuilder.name("J5").duration(10).priority(2).deadline(30).user(User.USER).build();

List<Job> tasks = List.of(job1, job2, job3, job4, job5);
JobScheduler sjfScheduler = new JobScheduler(new SjfStrategy(), threadManager);
sjfScheduler.scheduleJobs(tasks);

System.out.println("SJF");
threadManager.schedule(new SjfStrategy(), tasks);
threadManager.init(2);
JobScheduler fcfsScheduler = new JobScheduler(new FcfsStrategy(), threadManager);
fcfsScheduler.scheduleJobs(tasks);

// System.out.println("SJF");
// threadManager.schedule(new SjfStrategy(), tasks);

System.out.println("FCFS");
threadManager.schedule(new FcfsStrategy(), tasks);
// System.out.println("FCFS");
// threadManager.schedule(new FcfsStrategy(), tasks);
}
}
11 changes: 8 additions & 3 deletions Entities/Worker.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// Workers are threads that will execute the jobs in this system
public class Worker {
//jobs that will be assigned to this thread
List<String> jobs;
int availableAt;
int id;
private List<String> jobs;
private Integer availableAt;
private Integer id;

public int getId() { return id; }
public int getAvailableAt() {
Expand All @@ -18,6 +18,11 @@ public void setAvailableAt(int availableAt) {
this.availableAt = availableAt;
}

public List<String> getJobs(){
return jobs;
}

private Worker(){} // making a private constructor so that no one can make a worker with empty id
public Worker(int id) {
jobs = new ArrayList<>();
availableAt = 0;
Expand Down
18 changes: 18 additions & 0 deletions JobScheduler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Entities.Job;
import SchedulingStrategy.ISchedulingStrategy;
import Threads.ThreadManager;

import java.util.List;

public class JobScheduler {
private final ISchedulingStrategy strategy;
private final ThreadManager threadManager;
JobScheduler(ISchedulingStrategy strategy, ThreadManager threadManager){
this.strategy = strategy;
this.threadManager = threadManager;
}
public void scheduleJobs(List<Job> jobs){
strategy.run(threadManager,jobs);
threadManager.print();
}
}
9 changes: 7 additions & 2 deletions SchedulingStrategy/FcfsStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@

import Entities.Job;
import Entities.Worker;
import Threads.ThreadManager;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class FcfsStrategy implements ISchedulingStrategy {

@Override
public void run(PriorityQueue<Worker> workers, List<Job> jobs){
public void run(ThreadManager threadManager, List<Job> jobs){
// no need to sort the jobs assuming arrival time is 0 for all of them
readJobs(workers, jobs);
for(var j : jobs){
threadManager.assignJobToWorkerThread(j);
}
}
}
3 changes: 2 additions & 1 deletion SchedulingStrategy/ISchedulingStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import Entities.Job;
import Entities.Worker;
import Threads.ThreadManager;

import java.util.ArrayList;
import java.util.Comparator;
Expand All @@ -10,7 +11,7 @@

public interface ISchedulingStrategy {

void run(PriorityQueue<Worker> workers, List<Job> jobs);
void run(ThreadManager threadManager, List<Job> jobs);
default void readJobs(PriorityQueue<Worker> workers, List<Job> jobs) {
for(var job : jobs) {
Worker current = workers.poll();
Expand Down
17 changes: 14 additions & 3 deletions SchedulingStrategy/SjfStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@

import Entities.Job;
import Entities.Worker;
import Threads.ThreadManager;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class SjfStrategy implements ISchedulingStrategy {

/**
* Shortest Job first - SJF
* Shortest job first (SJF), is a scheduling policy that selects the waiting process with the smallest execution time to execute next.
* In case of tie choose the job according to the following order -
* 1. Priority (higher priority job gets scheduled first)
*/

@Override
public void run(PriorityQueue<Worker> workers, List<Job> tasks) {
public void run(ThreadManager threadManager, List<Job> tasks) {
List<Job> jobs = new ArrayList<>(tasks);
jobs.sort(Comparator.comparingInt(Job::getDuration));
readJobs(workers, jobs);
jobs.sort(Comparator.comparingInt(Job::getDuration).thenComparing(Job::getPriority));
for(var j : jobs){
threadManager.assignJobToWorkerThread(j);
}
}
}
46 changes: 40 additions & 6 deletions Threads/ThreadManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@
import Entities.Worker;
import SchedulingStrategy.ISchedulingStrategy;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.List;

// Holds instance of threads and abstracts it from client
// Responsibility :

/**
* Manage Thread LifeCycle : Creation, Job Assignment and Storage of Thread Workers
*/
public class ThreadManager {
private static ThreadManager INSTANCE = null;
PriorityQueue<Worker> pq;
private PriorityQueue<Worker> pq;

public ThreadManager() {
pq = new PriorityQueue<>(Comparator.comparingInt(Worker::getAvailableAt));
private ThreadManager() { // this should be private if you want to make it singleton.
pq = new PriorityQueue<>(Comparator.comparingInt(Worker::getAvailableAt)
.thenComparing(Worker::getId)
);
// so if 2 threads are getting available at same time, i should choose the one which has smaller id.
}

public static ThreadManager getInstance() {
Expand All @@ -24,6 +33,19 @@ public static ThreadManager getInstance() {
return INSTANCE;
}

public void assignJobToWorkerThread(Job j){
// polling the worker with the earliest available time.
if(pq.isEmpty()) throw new RuntimeException("No workers available");
var worker = pq.poll();
if(worker.getAvailableAt() <= j.getDeadline()){
worker.setAvailableAt(worker.getAvailableAt() + j.duration);
worker.addJob(j); // assigning the job
pq.add(worker); // adding the worker to the pool
}else {
pq.add(worker);
}
}

public void init(int numOfWorkers) {
if(numOfWorkers <= 0)
return;
Expand All @@ -35,8 +57,20 @@ public void init(int numOfWorkers) {
}
}

public void schedule(ISchedulingStrategy strategy, List<Job> jobs) {
strategy.run(pq, jobs);
init(pq.size());
public void reset(){
if(pq != null && !pq.isEmpty())
this.init(pq.size());
}

public void print(){
List<Worker> workers = new ArrayList<>();
while(!pq.isEmpty()){
workers.add(pq.poll());
}
workers.sort(Comparator.comparing(Worker::getId));
for(var w : workers){
System.out.println("Thread " + w.getId() + " : " + w.getJobs().toString());
}
}

}
Binary file added lld.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.