In an interview about multithreading I was asked to write code to satisfy the requirements below:
In the exercise you need to provide implementation of single-threaded TaskScheduler class with the following signatures:
TaskScheduler { TaskScheduler(List<Task> tasks) int getPriority() void execute()
where
Task
object is considered interruptible if it implementsInterruptible
interface.
Now I have to consider the below 4 requirements also in developing the class:
Define TaskScheduler and Task classes
Define classes, write a test or vice versa.
executeAllByPriority()
Add void executeAllByPriority() method to TaskScheduler, test and implement it.
executeAllByPriorityWithUninterruptableFirst()
Add void executeAllByPriorityWithUninterruptableFirst() method to TaskScheduler, implement and test it.
Bonus
Provide multi-threaded version of TaskScheduler such that it guarantees that a higher priority task always starts execution before a lower priority task.
Keeping these above 4 points in consideration I have coded the below program. Please advise whether it is the correct approach.
public class MultiThreadedTaskScheduler {
AtomicInteger priorityCounter = new AtomicInteger(-1);
private ExecutorService executorService = Executors.newFixedThreadPool(10);
private PriorityQueue<Task> taskQueue;
private static final PriorityComparator PRIORITY_COMPARATOR = new PriorityComparator();
public MultiThreadedTaskScheduler(List<Task> tasks){
this.taskQueue = new PriorityQueue<Task>(tasks.size(), PRIORITY_COMPARATOR);
this.taskQueue.addAll(tasks);
}
public void executeAllByPriority(){
executorService.submit(new Runnable() {
@Override
public void run() {
for (Task task : taskQueue) {
executeMethod(task);
}
}
});
}
private void executeMethod(Task task) {
if (task.getPriority() > priorityCounter.get() ){
task.execute();
priorityCounter.getAndSet(task.getPriority());
}
}
public void executeAllByPriorityWithUnInterruptableFirst(){
executorService.submit(new Runnable() {
@Override
public void run() {
PriorityQueue<Task> interruptedQueue = new PriorityQueue<Task>(taskQueue.size(),PRIORITY_COMPARATOR);
for (Task task : taskQueue) {
if (task instanceof Interruptible && ((Interruptible) task).isInterrupted() ){
interruptedQueue.add(task);
} else {
executeMethod(task);
}
}
for (Task task : interruptedQueue ){
executeMethod(task);
}
}
});
}
@Override
protected void finalize() throws Throwable {
super.finalize();
executorService.shutdown();
}
}