在反序列化后恢复它​​停止的程序

时间:2013-12-20 07:59:15

标签: java serialization deserialization

我有一个程序以不同的时间间隔执行事件。每个事件都分配了一个eventTime,如下所示:

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;
 }

我使用ArrayList来保存事件,使用for循环来启动事件。如果发生特殊事件,则使用序列化保存程序,然后终止:

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);
        }
    }
}

当我反序列化类并恢复程序时,ArrayList中剩下的任何事件都会执行,但它们会立即执行,因为它们的ready()要求已经满足。

如何更改序列化类中保存的旧System.currentTimeMillis(),以便稍后恢复程序时它将更新为新的System.currentTimeMillis()?

2 个答案:

答案 0 :(得分:2)

反序列化列表后,运行其中的对象并将保存的时间更新为新的时间。

你也可以通过重复反序列化过程来做一些奇特的事情,但老实说,只需设置值就可以了。更简单。

例如:

long startTime = System.currentTimeMillis();
for (Event e: eventList) {
      e.setEventTime(e.getDelayTime()+startTime);
}

如果您只想保留剩余的延迟,那么您还需要存储序列化的时间,以便计算出新的偏移量。实施这种方法:

long startTimeOffset = System.currentTimeMillis() - timeAtWhichWeSaved;
for (Event e: eventList) {
      e.setEventTime(e.getEventTime()+startTimeOffset);
}

答案 1 :(得分:2)

您不仅需要存储事件,还需要存储序列化的时间。然后在反序列化之后,计算出当前时间和序列化时间之间的差异,并相应地更新所有事件。

因此,假设在时间T = 10时,您创建了一个事件,在15个滴答时间内触发,因此T = 25。然后在T = 20时序列化数据 - 剩下5个滴答。

在T = 50时,您反序列化,并计算序列化时间(20)和现在(50)之间的差异 - 这意味着您需要为每个“就绪时间”添加30。您的活动将更新为在T = 55时触发,这是正确的,因为它在5个滴答时间内。

您可以使用自定义序列化代码执行此操作,序列化“剩余时间”而不是绝对截止日期,并反序列化到新的截止日期。