为了账号安全,请及时绑定邮箱和手机立即绑定

当同一对象运行回调时重新创建对象的设计模式

当同一对象运行回调时重新创建对象的设计模式

FFIVE 2023-06-08 20:26:20
这是我正在尝试做的一个简单的玩具示例。我有一个实现方法的 WebSocket 类onClose()。当 Socket 关闭时,它会触发事件处理程序(lambda 函数)。public class WebSocket {  ICallback cb;  public WebSocket(ICallback cb) {      this.cb = cb;      this.onClose(); // Simulating socket closing  }  public void onClose() {    this.cb.handle();  }  @FunctionalInterface  public static interface ICallback {    public abstract void handle();  }}在父类中,我创建了此类的一个新实例。当套接字关闭时,我必须重新创建此类的新实例。(旧的不能用)这是我的实现class Parent {  static WebSocket socket;  public static void main(String[] args) {    Parent.createSocket();  }  public static void createSocket() {    Parent.socket = new WebSocket(() -> { Parent.createSocket(); });  }}此代码有效但是每当onClose()被触发时,一个新的帧就会被添加到堆栈中。WebSocket在不增加堆栈大小的情况下重新创建对象的最佳模式是什么?运行一个不断检查套接字状态的线程是否是一种可行的方法?IE:while(socket.isOpen()) { Thread.sleep(1000);}createSocket();
查看完整描述

1 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

堆栈溢出的原因是您的回调永远不会完成 - 您只需创建一个新套接字并运行它,但旧套接字保持活动状态。下一个也一样,依此类推。


所以处理这个问题的一种方法是同时创建套接字,为方法提供onClose()一种实际终止的方法。


您可以通过将实际创作提交给ExecutorService; 单线程的很好,因为毕竟,您只希望在给定时间运行一个套接字。


class Parent {

    static WebSocket socket;

    // this is where the socket runs

    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();


    public static void main(String[] args) {

        createSocket();

    }


    private static void createSocket() {

        Parent.socket = new WebSocket(() -> {

            EXECUTOR.submit(Parent::createSocket);

        });

    }

}

这样,当回调被调用时onClose(),它会立即返回,并提交了新网络套接字的创建。该创建尚未发生,因为执行程序是单线程的,并且先前的套接字仍在该线程中运行。但是一旦完成,就会执行下一次提交——即刚刚提交的创建。


作为旁注,同时运行网络连接几乎总是一个好主意,因此主线程仍然可用于其他任务。


查看完整回答
反对 回复 2023-06-08
  • 1 回答
  • 0 关注
  • 99 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信