【问题标题】:Constantly check for change in Java?不断检查 Java 的变化?
【发布时间】:2011-02-14 04:34:13
【问题描述】:

如何检查布尔值以在给定时间段内更改状态,如果在该时间段内进行更改,则执行方法?

请用Java提供任何帮助。

谢谢。

【问题讨论】:

    标签: java methods boolean


    【解决方案1】:

    听起来你想在一个可以监听变化的类中包装一个布尔值。

    class ObservableBoolean {
    
        // "CopyOnWrite" to avoid concurrent modification exceptions in loop below.
        private final List<ChangeListener> listeners =
                new CopyOnWriteArrayList<ChangeListener>();
    
        private boolean value;
    
        public boolean getValue() {
            return value;
        }
    
        public synchronized void setValue(boolean b) {
            value = b;
            for (ChangeListener cl : listeners)
                cl.stateChanged(new ChangeEvent(this));
        }
    
        public synchronized void addChangeListener(ChangeListener cl) {
            listeners.add(cl);
        }
    
        public synchronized void removeChangeListener(ChangeListener cl) {
            listeners.remove(cl);
        }
    }
    

    然后简单地做:

    ObservableBoolean b = new ObservableBoolean();
    
    //...
    
    // Start the "period of time":
    b.addChangeListener(iWantToBeNotifiedOfChanges);
    
    // ...
    
    // End the "period of time":
    b.removeChangeListener(iWantToBeNotifiedOfChanges);
    

    这实际上是 MVC 模式(和观察者模式)的一个简单案例。在这种情况下,模型是 ObservableBoolean,视图将是希望收到更改通知的“视图”。

    如果你想避免看起来很奇怪的javax.swing...导入,你也可以编写自己的ChangeListener接口

    【讨论】:

    • +1 表示观察者模式。我想知道您是要监视布尔值本身,还是应该让正在更改状态的类拥有侦听器列表,并在它对布尔值执行 mod 时触发更改事件。
    • +1 ... 但有几点:监听器列表应该是最终的,getValue() 不同步,如果监听器在收到通知时尝试将自己作为监听器移除,这将导致并发修改异常。您可以通过使用 CopyOnWriteArrayList 而不是 ArrayList 来解决最后一个问题。
    • CopyOnWriteArrayList 方法的主要优点是,您只需在添加/删除侦听器时复制列表,这可能是一个远不如通知常见的事件。
    • @aioobe:我认为你永远不应该在保持同步锁的同时通知。您不知道谁将注册,因此您基本上是在进行所谓的“外星方法调用”。永远不要在持有同步锁的同时创建外星方法。
    • 我会在 java.beans 包中使用PropertyChangeListener,但同样的区别。有没有办法避免编写addChangeListenerremoveChangeListener 方法?另外,这不能参数化(不是boolean,而是Boolean)?
    【解决方案2】:

    最简单的方法是使用包装类...

    public class Bool
    {
        public Bool(){ _val = false; }
        public Bool(boolean val) { _val = val; }
    
        public boolean getValue(){ return _val; }
        public void setValue(boolean val){ 
             _changesupport.firePropertyChange("value",_val,_val=val);
        }
    
        public void addPropertyChangeListener(PropertyChangeListener listener ){
            _changesupport.addPropertyChangeListener(listener);
        }
    
        public void removePropertyChangeListener(PropertyChangeListener listener){
            _changesupport.removePropertyChangeListener( listener );
        }
    
        private boolean _val = false;
        private final PropertyChangeSupport _changesupport = new PropertyChangeSupport(this);
    }
    

    这是 Swing 中的常见模式,您可以使用PropertyChangeSupport 来简化对象的创建,您可以在这些对象上观察和侦听属性更改。使用此类类,您可以注册一个PropertyChangeListener 来处理生成的PropertyChangeEvents 该结果。

    【讨论】:

    • 很高兴PropertyChangeSupport。为什么它不位于更“通用”的包中?
    • PropertyChangeSupport +1。虽然我只是将其设为最终的和公开的,并跳过 Bool 类的添加和删除方法。
    【解决方案3】:

    使用Timer 或编写您自己的扩展Thread 的类。

    谷歌搜索这些东西应该会给你一个好的开始

    编辑:从问题来看,他的意图不是很清楚。也许他想在确切的时间段内调用某个方法,而不是在事件发生后立即调用。对于这种模式,我还是宁愿坚持使用定时器,或者编写自己的线程。编写自己的线程仍然是解释特定用户需求的最佳方式。另一方面,如果这真的是监听事件的情况,我的 Timer 模式将是完全错误的。

    示例:如果用户请求(reques = true),我想每 5 分钟更新一次数据库(想象网络浏览器游戏)。使用错误请求,我不需要更新数据库。立即更新数据库(例如游戏《部落战争》中拥有数千名玩家的统计数据)完全是矫枉过正。

    【讨论】:

    • 是的,但问题不是立即检查,而是在一定的时间(时间段)内检查。这取决于模型设计。扩展 Thread 类基本上是 Listeners 的实现(不是字面意思,但几乎相同)
    • “如果在该时间段内进行了更改,请执行一个方法”。我是说,如果在那段时间内进行了 两个 更改,您确实需要一个额外的布尔值 stateHasChanged 来跟踪这一点(否则很可能变化未被注意到)。
    • IF 太多。你可能是对的,也可能不是。一段真实的代码(不仅仅是理论问题)应该可以完全解决这个问题。
    • 你是程序员吗?两个“IF”对你来说太多了吗? ;-)
    【解决方案4】:

    似乎您应该寻求实现某种Model View Controller Pattern。 看看here

    基本思想是当布尔值改变时你应该触发一个事件,然后那个事件被触发,你的监听器应该处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      相关资源
      最近更新 更多