不断检查 Java 的变化?
Posted
技术标签:
【中文标题】不断检查 Java 的变化?【英文标题】:Constantly check for change in Java? 【发布时间】:2011-02-14 04:34:13 【问题描述】:如何检查布尔值以在给定时间段内更改状态,如果在该时间段内进行更改,则执行方法?
请用Java提供任何帮助。
谢谢。
【问题讨论】:
【参考方案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
,但同样的区别。有没有办法避免编写addChangeListener
和removeChangeListener
方法?另外,这不能参数化(不是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
基本思想是当布尔值改变时你应该触发一个事件,然后那个事件被触发,你的监听器应该处理它。
【讨论】:
以上是关于不断检查 Java 的变化?的主要内容,如果未能解决你的问题,请参考以下文章