Task Scheduler

import java.util.LinkedList;
import java.util.Queue;

public class TaskSchedulerByLanguageInstrinsics {

    private int maxNumRunningTasks;
    private int maxNumPendingTasks;
    private Queue<Runnable> pendingTasks = new LinkedList<>();

    public TaskSchedulerByLanguageInstrinsics(int maxRunning, int maxPending) {
        maxNumRunningTasks = maxRunning;
        maxNumPendingTasks = maxPending;
    }

    public synchronized boolean addTask(Runnable task) {
        if (pendingTasks.size() < maxNumPendingTasks) {
            pendingTasks.add(task);
            notify();
            return true;
        } else {
            return false;
        }
    }

    public synchronized void startTasks() {
        for (int i = 0; i < maxNumRunningTasks; ++i) {
            new Worker().start();
        }
    }

    private synchronized Runnable getNextTask() {
        if (pendingTasks.size() > 0) {
            return pendingTasks.remove();
        } else {
            return null;
        }
    }

    private synchronized void waitForNewTask() throws InterruptedException {
        wait();
    }

    private class Worker extends Thread {
        @Override
        public void run() {
            try {
                while(true) {
                    Runnable task = getNextTask();
                    if (task != null) {
                        task.run();
                    } else {
                        waitForNewTask();
                    }
                }
            } catch (InterruptedException ex) {
                System.err.println("Workers should not be interrupted.");
                System.exit(1);
            }
        }
    }

    // ******************Code below is the test driver, not part of the scheduler implementation.*************

    public static void main(String[] args) throws Throwable {
        TaskSchedulerByLanguageInstrinsics scheduler = new TaskSchedulerByLanguageInstrinsics(3, 5);
        boolean ret = true;
        Task initialTask = null;
        do {
            initialTask = getRandomTask();
            ret = scheduler.addTask(initialTask);
            if (ret) {
                System.out.println("Task " + initialTask.getTaskId() + " added to scheduler.");
            } else {
                System.out.println("Task " + initialTask.getTaskId() + " rejected by scheduler.");
            }
        } while (ret);
        System.out.println("Starting task scheduler.");
        scheduler.startTasks();
        Task newTask = initialTask;
        while (true) {
            // TODO: Change the frequency at which we add new jobs to see how the scheduler behaves.
            // E.g. 1000, 3000, 10000
            Thread.sleep(3000);
            System.out.println("Scheduling task " + newTask.getTaskId());
            ret = scheduler.addTask(newTask);
            if (ret) {
                System.out.println("Task " + newTask.getTaskId() + " added to scheduler.");
                newTask = getRandomTask();
            } else {
                System.out.println("Task " + newTask.getTaskId() + " rejected by scheduler.");
            }
        }

    }

    /**
     * Returns a task that takes a random amount of time between 3 and 8 seconds.
     */
    private static Task getRandomTask() {
        final double minTaskTime = 3000;
        final double taskTimeRange = 5000;
        return new Task((int) (minTaskTime + Math.random() * taskTimeRange));
    }

    private static class Task implements Runnable {

        private static int idCounter = 0;

        private int id;
        private int timeToCompleteMillis;

        public Task(int timeToCompleteMillis) {
            id = idCounter++;
            this.timeToCompleteMillis = timeToCompleteMillis;
        }

        public int getTaskId() {
            return id;
        }

        @Override
        public void run() {
            try {
                System.out.println("Performing task " + id + "...");
                Thread.sleep(timeToCompleteMillis);
                System.out.println("Task " + id + " completed. Time: " + timeToCompleteMillis + " millis.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

results matching ""

    No results matching ""