You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原型模式能否复制对象线程?状态模式用户禁用定时恢复重启失效问题

问题1:使用原型模式是否可以复制对象的线程?

原型模式的核心是拷贝对象的成员属性数据,不管是浅克隆还是深克隆,都仅能复制对象的静态状态信息。线程属于JVM调度的运行时资源,并不属于对象可序列化/可拷贝的成员范畴,线程的运行状态、调度逻辑都和当前JVM进程绑定,因此原型模式无法复制对象关联的线程。

问题2:状态模式实现用户定时恢复功能故障解决方案

故障根因

  • 你代码中启动的Timer是JVM进程级的运行时任务,序列化用户对象到.data文件时,不会持久化Timer的调度信息、运行状态。程序关闭后原有Timer随进程销毁,重启后反序列化得到的DisableState实例不会自动重新启动定时器。
  • 你当前注释了DisableState构造方法中date字段的赋值逻辑,没有持久化用户进入禁用状态的时间点,重启后无法判断是否已经达到24小时的解禁条件。

修复方案

  1. 保留禁用时间持久化逻辑
    取消DisableState构造方法中this.date = new Date();的注释,确保用户进入禁用状态的时间会被序列化存储到文件中,同时给AbstractState补充date字段的getter方法方便读取。
  2. 反序列化后补充状态校验逻辑
    在saveUser类的copy()方法返回用户对象前,增加状态校验逻辑:
if (user != null && "disabled".equals(user.getState().getStateName())) {
    DisableState disableState = (DisableState) user.getState();
    long disableTime = disableState.getDate().getTime();
    long now = System.currentTimeMillis();
    long passedTime = now - disableTime;
    // 已经过了24小时直接恢复
    if (passedTime >= 24 * 60 * 60 * 1000) {
        user.restore();
        // 恢复后更新持久化的用户状态
        save(user);
    } else {
        // 未到解禁时间,重新启动定时器,按剩余时间设置延迟
        long delay = 24 * 60 * 60 * 1000 - passedTime;
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                user.restore();
                try {
                    save(user);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, delay);
    }
}
  1. 优化建议
    给DisableState中Timer相关的临时运行时变量增加transient修饰,避免序列化时产生不必要的IO异常;如果有大量用户需要定时解禁,建议用ScheduledThreadPoolExecutor替代单线程的Timer,避免调度阻塞。

内容的提问来源于stack exchange,提问作者delia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 15:45:03