Java 恢复反序列化后停止的程序
我有一个以不同时间间隔执行事件的程序。每个事件都分配了一个事件时间,如下所示:Java 恢复反序列化后停止的程序,java,serialization,deserialization,Java,Serialization,Deserialization,我有一个以不同时间间隔执行事件的程序。每个事件都分配了一个事件时间,如下所示: public abstract class Event implements Serializable{ private long eventTime; protected final long delayTime; public Event(long delayTime) { this.delayTime = delayTime; System.out.println(thi
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);
}
}
}
公共抽象类控制器实现可序列化{
private List eventList=new ArrayList();
公共无效事件(事件c){
事件列表。添加(c);
}
公共摘要void saveState();
公共摘要无效关闭();
公开募捐{
while(eventList.size()>0)
对于(事件e:新阵列列表(事件列表))
如果(如ready()){
系统输出打印ln(e);
试一试{
e、 动作();
}
捕获(控制器异常){
System.err.println(“原因:+ex+”\n”);
System.out.println(“状态已保存”);
System.out.println(例如getErrorcode());
事件列表。删除(e);
System.out.println(事件列表);
saveState();
关机();
}
事件列表。删除(e);
}
}
}
当我反序列化类并还原程序时,所有留在ArrayList中的事件都会执行,但它们会立即执行,因为它们的ready()要求已经得到满足
如何更改保存在序列化类中的旧System.currentTimeMillis(),以便在以后恢复程序时,它将更新为新System.currentTimeMillis() 反序列化列表后,运行列表中的对象,并将保存的时间更新为新的计时 您也可以在反序列化过程中做一些花哨的事情,但老实说,仅仅通过设置值来运行要简单得多 例如:
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);
}
反序列化列表后,运行其中的对象,并将保存的时间更新为新的计时 您也可以在反序列化过程中做一些花哨的事情,但老实说,仅仅通过设置值来运行要简单得多 例如:
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);
}
您不仅需要存储事件,还需要存储序列化的时间。然后在反序列化之后,计算出当前时间和序列化时间之间的差异,并相应地更新所有事件 所以假设在时间T=10时,您创建了一个事件以在15个时间点内触发,所以T=25。然后,在T=20时,您序列化了数据-剩下5个刻度 在T=50时,您需要反序列化,并计算序列化时间(20)和现在(50)之间的差异——这意味着您需要在每个“准备时间”中添加30。您的事件将被更新为在T=55时触发,这是正确的,因为它再次在5个时间点内触发
您可以使用自定义序列化代码来实现这一点,序列化“剩余时间量”而不是绝对截止日期,并反序列化到新的截止日期。您不仅需要存储事件,还需要存储序列化的时间。然后在反序列化之后,计算出当前时间和序列化时间之间的差异,并相应地更新所有事件 所以假设在时间T=10时,您创建了一个事件以在15个时间点内触发,所以T=25。然后,在T=20时,您序列化了数据-剩下5个刻度 在T=50时,您需要反序列化,并计算序列化时间(20)和现在(50)之间的差异——这意味着您需要在每个“准备时间”中添加30。您的事件将被更新为在T=55时触发,这是正确的,因为它再次在5个时间点内触发 您可以使用自定义序列化代码来实现这一点,序列化“剩余时间量”而不是绝对截止日期,并反序列化到新的截止日期