原型模式能否复制对象线程?状态模式用户禁用定时恢复重启失效问题
问题1:使用原型模式是否可以复制对象的线程?
原型模式的核心是拷贝对象的成员属性数据,不管是浅克隆还是深克隆,都仅能复制对象的静态状态信息。线程属于JVM调度的运行时资源,并不属于对象可序列化/可拷贝的成员范畴,线程的运行状态、调度逻辑都和当前JVM进程绑定,因此原型模式无法复制对象关联的线程。
问题2:状态模式实现用户定时恢复功能故障解决方案
故障根因
- 你代码中启动的
Timer是JVM进程级的运行时任务,序列化用户对象到.data文件时,不会持久化Timer的调度信息、运行状态。程序关闭后原有Timer随进程销毁,重启后反序列化得到的DisableState实例不会自动重新启动定时器。 - 你当前注释了
DisableState构造方法中date字段的赋值逻辑,没有持久化用户进入禁用状态的时间点,重启后无法判断是否已经达到24小时的解禁条件。
修复方案
- 保留禁用时间持久化逻辑
取消DisableState构造方法中this.date = new Date();的注释,确保用户进入禁用状态的时间会被序列化存储到文件中,同时给AbstractState补充date字段的getter方法方便读取。 - 反序列化后补充状态校验逻辑
在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); } }
- 优化建议
给DisableState中Timer相关的临时运行时变量增加transient修饰,避免序列化时产生不必要的IO异常;如果有大量用户需要定时解禁,建议用ScheduledThreadPoolExecutor替代单线程的Timer,避免调度阻塞。
内容的提问来源于stack exchange,提问作者delia
相关产品推荐
相关产品推荐

