CompletableFuture<Void> scheduleTaskUtil(Task task, Executor executor) {
        CompletableFuture<Void> f = taskTracker.get(task.name());
        if (f != null) {
            return f;
        }
        if (task.dependencies().isEmpty()) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> task.execute(), executor);
            taskTracker.put(task.name(), future);
            return future;
        }
        CompletableFuture<Void> future = CompletableFuture.completedFuture(null);;
        for (Task upstreamTask : task.dependencies()) {
            future = future.thenAcceptBothAsync(scheduleTaskUtil(upstreamTask, executor), (a, b) -> {}, executor);
        }
        future = future.thenRunAsync(() -> task.execute(), executor);
        taskTracker.put(task.name(), future);
        return future;
    }
Given a Task with list of its dependencies and execute method. Run the task such that dependencies are executed first.
You are given x number of threads. Increase parallelism as much as possible.
src/com/interview/multithreaded/DependencyTaskExecutor.java