gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 01:47:12 24 4
gpt4 key购买 nike

这是我正在尝试做的事情的一个简单的玩具示例。

我有一个 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() 时,就会将一个新帧添加到堆栈中。如果运行足够长的时间并假设有许多错误导致套接字关闭,最终会导致 StackOverflowError。

<强> Running Example

在不增加堆栈大小的情况下重新创建 WebSocket 对象的最佳模式是什么?

运行一个连续检查套接字状态的线程是一种可行的方法吗?即:

while(socket.isOpen()) {
Thread.sleep(1000);
}
createSocket();

最佳答案

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

因此,处理此问题的一种方法是同时创建套接字,为 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() 调用回调时,它会立即返回,并提交新 Web 套接字的创建。该创建尚未发生,因为执行器是单线程的,并且先前的套接字仍在该线程中运行。但一旦完成,就会执行下一次提交 - 即刚刚提交的创建。

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

关于java - 当同一对象运行回调时重新创建对象的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57518650/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com