From e41342f0cebff5a1c6b090c65a1e67a2ee31810c Mon Sep 17 00:00:00 2001 From: Jade Date: Tue, 11 May 2021 15:04:15 +0800 Subject: [PATCH] simulationJob --- .../joylink/rtss/simulation/Simulation.java | 15 +++-- .../simulation/job/SimulationDelayJob.java | 30 ++------- .../simulation/job/SimulationFixedJob.java | 17 ++++- .../rtss/simulation/job/SimulationJob.java | 30 ++++++++- .../job/SimulationScheduledJob.java | 65 +++++-------------- 5 files changed, 74 insertions(+), 83 deletions(-) diff --git a/src/main/java/club/joylink/rtss/simulation/Simulation.java b/src/main/java/club/joylink/rtss/simulation/Simulation.java index b856a235d..639c9347d 100644 --- a/src/main/java/club/joylink/rtss/simulation/Simulation.java +++ b/src/main/java/club/joylink/rtss/simulation/Simulation.java @@ -133,7 +133,12 @@ public abstract class Simulation { + if (getSystemTime().compareTo(simulationJob.runtime) >= 0) { + simulationJob.job.run(); + simulationJob.afterRun(); + } + }); } catch (Throwable e) { this.runError(e); log.error(String.format("仿真[%s]主线程逻辑执行异常,仿真停止运行", this.id), e); @@ -191,7 +196,7 @@ public abstract class Simulation= 0) { - this.job.run(); - simulation.removeJob(getId()); - } + public void afterRun() { + simulation.removeJob(name); } } diff --git a/src/main/java/club/joylink/rtss/simulation/job/SimulationFixedJob.java b/src/main/java/club/joylink/rtss/simulation/job/SimulationFixedJob.java index 763318241..2195c884d 100644 --- a/src/main/java/club/joylink/rtss/simulation/job/SimulationFixedJob.java +++ b/src/main/java/club/joylink/rtss/simulation/job/SimulationFixedJob.java @@ -3,15 +3,26 @@ package club.joylink.rtss.simulation.job; import club.joylink.rtss.simulation.Simulation; import lombok.extern.slf4j.Slf4j; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.concurrent.TimeUnit; + @Slf4j public final class SimulationFixedJob extends SimulationScheduledJob { - public SimulationFixedJob(Simulation simulation, String name, SimulationJob job, int rate) { + public SimulationFixedJob(Simulation simulation, String name, Runnable job, int rate) { super(simulation, name, job, rate); } @Override - public void run() { - super.doRun((rate, speed) -> rate * speed); + public void afterRun() { + LocalDateTime systemTime = simulation.getSystemTime(); + // 实际运行间隔,单位ns + long runPeriod = TimeUnit.MILLISECONDS.toNanos(this.rate) * simulation.getSpeed(); + // 弥补非整数倍的情况 + long l = Duration.between(this.runtime, systemTime).toNanos(); + long l1 = l % runPeriod; + long add = runPeriod - l1; + this.runtime = systemTime.plusNanos(add); } } diff --git a/src/main/java/club/joylink/rtss/simulation/job/SimulationJob.java b/src/main/java/club/joylink/rtss/simulation/job/SimulationJob.java index 029f2e65b..0ca9a752a 100644 --- a/src/main/java/club/joylink/rtss/simulation/job/SimulationJob.java +++ b/src/main/java/club/joylink/rtss/simulation/job/SimulationJob.java @@ -1,6 +1,32 @@ package club.joylink.rtss.simulation.job; -public interface SimulationJob { +import club.joylink.rtss.simulation.Simulation; +import lombok.Getter; - void run(); +import java.time.LocalDateTime; + +@Getter +public abstract class SimulationJob { + Simulation simulation; + public String name; + /** + * 运行逻辑 + */ + public Runnable job; + /** + * 执行时间 + */ + public LocalDateTime runtime; + + public SimulationJob(Simulation simulation, String name, Runnable job, LocalDateTime runtime) { + if (null == job) { + throw new IllegalArgumentException("job must not be null"); + } + this.simulation = simulation; + this.name = name; + this.job = job; + this.runtime = runtime; + } + + public abstract void afterRun(); } diff --git a/src/main/java/club/joylink/rtss/simulation/job/SimulationScheduledJob.java b/src/main/java/club/joylink/rtss/simulation/job/SimulationScheduledJob.java index ed8343b34..d32ba444a 100644 --- a/src/main/java/club/joylink/rtss/simulation/job/SimulationScheduledJob.java +++ b/src/main/java/club/joylink/rtss/simulation/job/SimulationScheduledJob.java @@ -6,69 +6,24 @@ import lombok.extern.slf4j.Slf4j; import java.time.Duration; import java.time.LocalDateTime; import java.util.concurrent.TimeUnit; -import java.util.function.BiFunction; @Slf4j -public class SimulationScheduledJob implements SimulationJob { - Simulation simulation; - private String name; - /** - * 运行逻辑 - */ - private SimulationJob job; +public class SimulationScheduledJob extends SimulationJob { + /** * 原始频率,单位ms */ final int rate; - LocalDateTime nextRunTime; // 下次需要执行的时刻(后续基于性能考虑可换为long类型) - - public SimulationScheduledJob(Simulation simulation, String name, SimulationJob job, int rate) { - if (null == job) { - throw new IllegalArgumentException("job must not be null"); - } + public SimulationScheduledJob(Simulation simulation, String name, Runnable job, int rate) { + super(simulation, name, job, simulation.getSystemTime()); if (rate <= 0) { throw new IllegalArgumentException("rate must bigger than 0"); } - this.simulation = simulation; - this.name = name; - this.job = job; this.rate = rate; } public static final long TIMEOUT_NANO = TimeUnit.MILLISECONDS.toNanos(5); - @Override - public void run() { - doRun((rate, speed) -> rate); - } - - void doRun(BiFunction consumer) { - LocalDateTime systemTime = simulation.getSystemTime(); - if (this.nextRunTime == null || systemTime.compareTo(this.nextRunTime) >= 0) { - long start = System.nanoTime(); - this.job.run(); - long used = System.nanoTime() - start; - if (used > TIMEOUT_NANO) { - log.warn(String.format("仿真任务[%s]执行耗时[%sns]超过[%sns],请检查并调优", - this.name, used, TIMEOUT_NANO)); - } - // 实际运行间隔,单位ns - Long runPeriod = consumer.apply(TimeUnit.MILLISECONDS.toNanos(this.rate), simulation.getSpeed()); - if (this.nextRunTime != null) { - // 弥补非整数倍的情况 - long l = Duration.between(this.nextRunTime, systemTime).toNanos(); - long l1 = l % runPeriod; - long add = runPeriod - l1; - this.nextRunTime = systemTime.plusNanos(add); - } else { - this.nextRunTime = systemTime.plusNanos(runPeriod); - } - } - } - - public String getName() { - return name; - } /** * @@ -78,4 +33,16 @@ public class SimulationScheduledJob implements SimulationJob { public int calculateRunTimes(long interval) { return (int) (interval / TimeUnit.MILLISECONDS.toNanos(this.rate)); } + + @Override + public void afterRun() { + LocalDateTime systemTime = simulation.getSystemTime(); + // 实际运行间隔,单位ns + long runPeriod = TimeUnit.MILLISECONDS.toNanos(this.rate); + // 弥补非整数倍的情况 + long l = Duration.between(this.runtime, systemTime).toNanos(); + long l1 = l % runPeriod; + long add = runPeriod - l1; + this.runtime = systemTime.plusNanos(add); + } }