我有许多线程对对象执行不同的操作,当几乎50%的任务完成时,我想要序列化所有内容(可能是我想要关闭我的机器)。
当我回来时,我想从我离开的地方开始。 我们怎样才能实现?
这就像在播放时保存任何游戏的对象状态一样。 通常我们保存对象的状态并检索回来。但在这里我们存储其进程的计数/状态。
例如:
我有一个为5万名员工创建工资表的线程。
其他主题是为同样的5万名员工创建评估信。
另一个主题是向5万名员工发送“新年快乐”电子邮件。
所以想象多个操作。
现在我想在50%的任务完成之间关闭。说已经写了25-30万名员工工资表和25-30万的评估信等等。 当我第二天回来的时候,我想从我离开的地方开始这个过程。
这就像 resume 。
答案 0 :(得分:2)
我不确定这是否有帮助,但如果线程通过内存中队列进行通信,则可以实现此目的。
要序列化整个应用程序,您需要做的是禁用队列的消耗,当所有线程都空闲时,您将到达一个“安全点”,您可以在其中序列化整个状态。你需要跟踪你产生的所有线程,以确定它们是否处于空闲状态。
您可以使用其他技术(可能是Java代理吗?)冻结JVM并允许您转储整个状态,但我不知道这是否存在。
答案 1 :(得分:1)
与保存对象状态没什么不同。 只为不同类型的输入维护单独的队列。并且在每次启动(第一次启动或重新启动)时检查这些队列,如果不是空的,则通过启动新进程但使用剩余数据恢复“已停止的进程”。
说对于前。一个应用程序正在发送消息,你退出的应用程序剩余10 msg。拥有一个全局队列,应用程序的senderMethod将在每次启动时检查。所以在这种情况下,它将在待处理队列中有10msg,因此它将继续发送剩余的消息。
修改强> 基本上,对于所有可恢复的过程'说pr1,pr2 .... prN,保持输入队列,比如q1,q2 ..... qN。 queue应删除已处理的元素,以仅包含挂起的输入。一旦你暂停系统。存储这些队列,并在重新启动时恢复它们。有一个共同的例程说resumeOperation,它将调用所有可恢复的进程(pr1,pr2 .... prN)。因此它将触发非0队列的方法的执行。其中复制恢复行为。
答案 2 :(得分:0)
Java提供了java.io.Serializable
接口来指示类中的序列化支持。
您没有提供有关任务的大量信息,因此很难给出答案。
考虑任务的一种方法是通用算法,可以分成几个步骤。这些步骤中的每一步反过来都是任务本身,所以你应该在这里看到一个模式。
通过将每个算法分成小块,直到你无法进一步划分,你就可以很好地了解你的任务可以在哪里被中断并在以后恢复。 任务的结果可以是:
成功:任务返回预期类型的值
失败:某种程度上,某些事情在进行计算时没有正确
中断计算:工作未完成,但可能会在稍后恢复,返回值为任务状态
(请注意,后一种情况可能被认为是失败的一个子问题,您可以根据需要组织协议)。
取决于您如何生成中断事件(它是从主线程传递到工作线程的消息吗?它会是异常吗?),该事件必须在任务树中冒泡,并触发每个任务评估其工作是否可以恢复,然后为包含它的大型任务提供自身的序列化版本。
答案 3 :(得分:0)
我不认为序列化是解决这个问题的正确方法。你想要的是持久性队列,你从处理它时删除它。每次启动程序时,您只需从头开始处理队列。有许多实现持久队列的方法,但考虑到操作的规模,可以想到数据库。