code: /**
   * Integrates input function K over time
   * S + (t1 - t0) * (K(t1) + K(t0)) / 2
   */
  public class Integrator {
  
      public interface Function {
          double apply(double timeSinceStartInSeconds);
      }
  
      private final long start;
      private volatile boolean running;
  
      private Function func;
      private double t0;
      private double v0;
      private double sum;
  
      public Integrator(Function func) {
          this.start = System.nanoTime();
          setFunc(func);
          new Thread(this::integrate).start();
      }
  
      public void setFunc(Function func) {
          this.func = func;
          v0 = func.apply(0.0);
          t0 = 0;
      }
  
      public double getOutput() {
          return sum;
      }
  
      public void stop() {
          running = false;
      }
  
      private void integrate() {
          running = true;
          while (running) {
              try {
                  Thread.sleep(1);
                  update();
              } catch (InterruptedException e) {
                  return;
              }
          }
      }
  
      private void update() {
          double t1 = (System.nanoTime() - start) / 1.0e9;
          double v1 = func.apply(t1);
          double rect = (t1 - t0) * (v0 + v1) / 2;
          this.sum += rect;
          t0 = t1;
          v0 = v1;
      }
  
      public static void main(String[] args) throws InterruptedException {
          Integrator integrator = new Integrator(t -> Math.sin(Math.PI * t));
          Thread.sleep(2000);
  
          integrator.setFunc(t -> 0.0);
          Thread.sleep(500);
  
          integrator.stop();
          System.out.println(integrator.getOutput());
      }
  }
  