【问题标题】:Self removable resource from flyweight来自享元的自可移除资源
【发布时间】:2016-11-15 16:37:44
【问题描述】:

我正在使用需要关闭的不同资源的应用程序,同时使用反应流。

我有一个基于享元模式的工厂,它保持对对象的引用,它们实现了 AutoCloseable 接口。问题是我在 Autocloseable 类中使用 close(), 这是我的问题:删除对工厂内封闭资源的引用的最佳解决方案是什么?我可以抛出某种事件并在工厂中捕获它​​,还是在每个可以关闭资源的操作之后我应该遍历引用映射并删除关闭的资源?

为了更好的上下文: 我正在使用响应式 Observable 发出目录事件(创建、删除文件/目录),并且在每个订阅者取消订阅它之后,我正在关闭我正在使用的 WatchService。

编辑#1

我的工厂类如下所示:

public final class Factory {

    private final ConcurrentHashMap<String, ReactiveStream> reactiveStreams = new ConcurrentHashMap<>();

    public ReactiveStream getReactiveStream(Path path) throws IOException {

        ReactiveStream stream = reactiveStreams.get(path.toString());

        if (stream != null) return stream;

        stream = new ReactiveStream(path);
        reactiveStreams.put(path.toString(), stream);

        return stream;

    }

}

这是我的 ReactiveStream 类的样子:

public class ReactiveStream implements AutoCloseable {

    (...)
    private WatchService service;
    private Observable<Event> observable;

    public Observable<Event> getObservable() throws IOException {

        (...) // where i create observable

        return observable;
    }

    (...)

    @Override
    public void close() throws IOException {
        service.close();
    }
}

如你所见,我有一个工厂,它保留对 ReactiveStream 类的引用,它在可观察后关闭自身将不再被订阅(我以我使用 doOnUnsubscribe(() -> close() 的方式这样做)在 observable 上使用 share() 之前,因此当没有订阅者时,将调用 doOnUnsubscribe )。

我的问题是,我如何才能从 Factory 中删除对已关闭 ReactiveStream 的引用?

编辑#2

observable = Observable.fromCallable(new EventObtainer()).flatMap(Observable::from).subscribeOn(Schedulers.io()).repeat().doOnUnsubscribe(() -> {
                try {
                    close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).share();

以下是我创建 observable 的方式。 EventObtainer 是 ReactiveStream 中的嵌套类,它使用 WatchService 需要在每个订阅者停止订阅后关闭。

【问题讨论】:

  • 非常不明确的问题。我觉得你描述的大部分与你遇到的问题无关,你遇到的问题描述的很肤浅。
  • 我添加了代码片段以便更好地理解代码
  • 显示你调用doOnUnsubscribe()的代码。
  • ReactiveStream 类中,您应该保留对反应流映射或工厂的引用,以便在 close() 中您可以将其从映射中删除。
  • 我不知道您将如何发送信号。另一个更复杂的选择是拥有一个完整的第三种机制,工厂和流都引用它,并通过它进行通信。就像您已经拥有的发布/订阅的东西一样,但专门用于有关注销的通信。

标签: java caching design-patterns reactivex flyweight-pattern


【解决方案1】:

今天我的同事告诉我解决此问题的最佳解决方案。所以我创建了界面:

@FunctionalInterface
public interface CustomClosable {

    void onClosing();

}

并在构造函数中添加这个接口的引用到ReactiveStream。

现在我正在调用 onClosing.onClosing() 我需要关闭资源的地方。

感谢工厂类负责声明关闭资源后应该做什么,而且我没有循环依赖,所以我的 ReactiveStream 类可以重复使用很多次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多