【问题标题】:Should we use WeakReference in Observer Pattern? [duplicate]我们应该在观察者模式中使用弱引用吗? [复制]
【发布时间】:2016-02-02 19:57:18
【问题描述】:

我正在通过tutorial 学习并尝试在 Java 中实现观察者模式。我一直纠结于是否应该使用WeakReference 来让主题保持观察者。

对于下面的实现,SubjectBinaryObserver 相互持有强引用,这恐怕会阻止 GC 收集未使用的 Subject

所以我的问题是,我应该使用List<WeakReference<Observer>> observers 而不是List<Observer> observers

Subject.java

public class Subject {

   private List<Observer> observers = new ArrayList<Observer>();
   private int state;

   public int getState() {
      return state;
   }

   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }

   public void attach(Observer observer){
       observers.add(observer);
   }

   public void notifyAllObservers(){
       for (Observer observer : observers) {
           observer.update();
       }
   }
}

Observer.java

public abstract class Observer {
    protected Subject subject;
    public abstract void update();
}

BinaryObserver.java

public class BinaryObserver extends Observer{

    public BinaryObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("Binary String: " + Integer.toBinaryString());
    }
}

ObserverPatternDemo.java

public class ObserverPatternDemo {
    public static void main(String[] args) {
       Subject subject = new Subject();

       new BinaryObserver(subject);

       System.out.println("First state change: 15");
       subject.setState(15);
    }
}

【问题讨论】:

  • 弱引用是邪恶的,只有在你喜欢追逐错误时才使用它们。注意:Java 的 GC 很聪明
  • 让我修改@SleimanJneidi 的声明:Java 的 GC 非常非常智能。它基于“可达性”工作 - 如果 SubjectObserver 都不是“可达性”(本质上:无法从任何以 main() 方法中的对象开头的对象引用链访问它们) ,然后可以收集它们。它们相互引用并不重要。这些引用仅确保如果一个是可访问的,那么另一个也是。如果两者都无法到达,它不会不必要地让它们保持活力。
  • 谢谢~但是我们什么时候应该使用WeakReference?我认为观察者模式是 WeakReference 的一个很好的例子,因为在 C++ 中 oberser 模式是 weak_ptr 的一个很好的例子...
  • @Hackjustu 如果你希望你的程序依赖于 GC 的行为而变得不可预测,你可以使用 Wea​​kReference
  • 相信 GC。如果您关心性能,不如尝试不同的配置:gc 的类型(g1、parallel、...)、young gen 空间等。

标签: java design-patterns


【解决方案1】:

您不必使用弱引用。你在做什么很好。 Java GC 已经处理循环引用。如果循环引用图是 ISLAND,Java GC 将收集整个循环引用图(没有来自根的图的传入引用 - 您可以认为整个图是一个大对象,GC 将收集这个大对象如果有没有引用)

看看这个:How does Java Garbage Collection work with Circular References?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多