From a9724d9d4cb5563eef429f02f43cc6a5ba6ccdbe Mon Sep 17 00:00:00 2001 From: Nullkat Date: Wed, 30 Jun 2021 19:59:30 +0300 Subject: [PATCH] Developed module loader algorithm --- .../progressia/ProgressiaLauncher.java | 3 +- .../progressia/common/modules/Task.java | 8 +-- .../common/modules/TaskManager.java | 71 ++++++++++++++----- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java index f8d886e..741d599 100644 --- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java +++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java @@ -32,7 +32,8 @@ public class ProgressiaLauncher { arguments = args.clone(); setupCrashReports(); proxy.initialize(); - TaskManager.startLoading(); + TaskManager tm = new TaskManager(); + tm.startLoading(); } private static void setupCrashReports() { diff --git a/src/main/java/ru/windcorp/progressia/common/modules/Task.java b/src/main/java/ru/windcorp/progressia/common/modules/Task.java index b9a602e..76ef83c 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/Task.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/Task.java @@ -36,6 +36,7 @@ public abstract class Task "The following required Tasks are not done:\n%s", StringUtil.iterableToString(undoneTasks, "\n")); } else { + isActive = true; perform(); isDone = true; } @@ -49,12 +50,11 @@ public abstract class Task } public boolean isActive() { return isActive; } - - public void setActive(boolean value) { isActive = value; } public boolean canRun() { - for (Task t : requiredTasks) { - if (!t.isDone()) return false; + if (this.isActive) return false; + for (Task reqT : requiredTasks) { + if (!reqT.isDone()) return false; } return true; } diff --git a/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java b/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java index bc8c395..457d5ce 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java @@ -8,25 +8,30 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +//TODO Maybe I want to make it singleton @"Nullkat" +//TODO Optimize task iteration: If task is not runnable check its requirement tasks + public class TaskManager { - private static final List tasks = new ArrayList<>(); - private static final List modules = new ArrayList<>(); - private static final ThreadFactory threadFactory = new ThreadFactoryBuilder() + private final List tasks = new ArrayList<>(); + private final List modules = new ArrayList<>(); + private final ThreadFactory threadFactory = new ThreadFactoryBuilder() .setNameFormat("LogicCore-%d") .build(); + private boolean wakeUpFlag = false; //Thread pool with size of logical cores of CPU - private static final ExecutorService executorService = + private final ExecutorService executorService = Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors() , threadFactory); - public static void registerModule(Module module) { + public void registerModule(Module module) { tasks.addAll(module.getTasks()); modules.add(module); } - public static void startLoading() { + public void startLoading() { + //DEBUG START Module mod = new Module("Module:Mod"); Task task = new Task("Task:Task") { @Override @@ -35,6 +40,11 @@ public class TaskManager { while(i < 1000000) { i++; } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } System.out.println("Task " + getId() + "has been performed by" + Thread.currentThread().getName()); } }; @@ -45,6 +55,11 @@ public class TaskManager { while(i < 1000000) { i++; } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } System.out.println("Task " + getId() + "has been performed by" + Thread.currentThread().getName()); } }; @@ -55,6 +70,11 @@ public class TaskManager { while(i < 1000000) { i++; } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } System.out.println("Task " + getId() + "has been performed by" + Thread.currentThread().getName()); } }; @@ -62,35 +82,50 @@ public class TaskManager { mod.addTask(task1); mod.addTask(task2); registerModule(mod); + //DEBUG END - while (!tasks.isEmpty()) { + for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { executorService.submit(() -> { - while (true) { + while (!tasks.isEmpty()) { Task t = getRunnableTask(); - if(t == null) { - break; + if (t == null) { + while (!wakeUpFlag) { + try { + System.out.println(Thread.currentThread().getName() + " go to sleep"); + synchronized (tasks) { + tasks.wait(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println(Thread.currentThread().getName() + " wake up"); + wakeUpFlag = false; } else if (!t.isActive()) { - t.setActive(true); - removeTask(t); t.run(); + removeTask(t); + wakeUpFlag = true; + synchronized (tasks) { + tasks.notifyAll(); + } } + //DEBUG + assert t != null; + System.out.println(Thread.currentThread().getName() + " has iterated && Task id:" + t.getId()); } - System.out.println(Thread.currentThread().getName() + " has been stopped!"); - Thread.yield(); + System.out.println(Thread.currentThread().getName() + " has completed its work!"); }); } - - executorService.shutdownNow(); } - private static void removeTask(Task task) { + private void removeTask(Task task) { synchronized (tasks) { tasks.remove(task); } } - public static Task getRunnableTask() { + public Task getRunnableTask() { synchronized (tasks) { for (Task t : tasks) { if (t.canRun()) return t;