Resuming an program where it left off after deserialization

I have a program that executes events at different time intervals. Each event is assigned an eventTime like this:

public abstract class Event implements Serializable{
  private long eventTime;
  protected final long delayTime;


  public Event(long delayTime) {
      this.delayTime = delayTime;
      System.out.println(this.delayTime);
      start();
  }

  public void start() { // Allows restarting
    eventTime = System.currentTimeMillis() + delayTime;

  }

  public boolean ready() {
    return System.currentTimeMillis() >= eventTime;
  }

  public abstract void action() throws ControllerException;
 }

I use an ArrayList to hold the events and a for loop to launch the events. If a special event occurs then the program is saved using serialization and then terminated:

public abstract class Controller implements Serializable{

    private List<Event> eventList = new ArrayList<Event>(); 
    public void addEvent(Event c) { 
        eventList.add(c); 
    }

    public abstract void saveState();
    public abstract void shutdown();

    public void run() {
       while(eventList.size() > 0)

       for(Event e : new ArrayList<Event>(eventList))
          if(e.ready()) {
              System.out.println(e);
          try {
              e.action();
          }
          catch(ControllerException ex) {
              System.err.println("Reason: " + ex + "\n");
              System.out.println("State has been saved");
              System.out.println(ex.getErrorcode());
              eventList.remove(e);
              System.out.println(eventList);
              saveState();
              shutdown(); 
          }
          eventList.remove(e);
        }
    }
}

When I deserialize the class and restore the program, any events that were left in the ArrayList execute, but they execute immediately because their ready() requirement has already been satisfied.

How can I change the old System.currentTimeMillis() that was saved in the serialized class so that when I resume the program at a later time it will update to the new System.currentTimeMillis() ?

Jon Skeet
people
quotationmark

You would need to store not just the events, but also the time at which you serialized. Then after deserializing, work out the difference between the current time and the serialization time, and update all the events accordingly.

So suppose at time T=10 you created an event to fire in 15 ticks time, so T=25. Then at T=20 you serialized the data - leaving 5 ticks remaining.

At T=50 you deserialize, and work out the difference between serialization time (20) and now (50) - which means you need to add 30 to each "ready time". Your event will be updated to fire at T=55, which is correct as again it's in 5 ticks time.

You could potentially do this with custom serialization code instead, serializing "amount of time left" instead of the absolute deadline, and deserializing to a new deadline.

people

See more on this question at Stackoverflow