【问题标题】:Codename One and Java synchronized keyword代号一和Java同步关键字
【发布时间】:2018-10-02 00:55:02
【问题描述】:

我怀疑我的 Codename One 项目中的一个错误是由同一个侦听器的并发执行引起的(如果用户非常快速地多次点击按钮,在它结束执行之前调用它的侦听器) ...我在代码中加了一个lock变量,避免同时执行多个,这样就解决了这个bug。

这是我第一次遇到这种问题。在网上阅读,建议使用synchronized Java 关键字(但我不确定它在这种情况下是否有用)。

我的问题是,Codename One 是否支持 synchronized Java 关键字。

【问题讨论】:

    标签: codenameone


    【解决方案1】:

    synchronized 在 Codename One 中运行良好,但如果您使用动作侦听器,它不太可能解决问题,除非我们有一个巨大无法想象的错误。

    在 EDT 上调用所有事件、绘制、生命周期方法等。它是一个线程,因此两次单击按钮将发生在一个线程上。 synchronized 将毫无意义。 EDT 用于从触摸屏交互一直到组件本身的事件,您可以通过isEDT() 方法对其进行测试。

    更有可能的情况是按钮上的一个动作侦听器使用invokeAndBlock,这可能会在事件调度链中触发奇怪的副作用。 invokeAndBlock() 内部由 AndWait 方法、对话框等使用。

    【讨论】:

    • 非常感谢您提供有趣且清晰的答案。我很困惑,因为我认为 ActionListener 的执行是在一个单独的线程中。也许我找到了错误的真正原因:使用animateUnlayout(立即返回,允许同一侦听器的另一个执行开始而无需等待动画结束)而不是animateUnlayoutAndWait(阻止之前执行另一个侦听器动画结束)。在animateUnlayout的情况下,动画是在EDT内部还是外部执行?我问这个是因为它会立即返回。
    • 两个动画都在 EDT 上执行 100%。动画只是打开一个“标志”,导致动画为每个 EDT 循环(AKA 滴答声)运行。 AndWait 方法使用invokeAndBlock 打开一个只等待的线程(不做任何其他事情)。 invokeAndBlock 获取 EDT 并使其保持运行,但紧随其后的行不会出现,因为它们已经在执行过程中。所以一旦invokeAndBlock 完成下一行(以及链中的下一个事件)就会被执行。
    • 例如如果 Button 有 3 个侦听器,而侦听器 2 有 10 行。第 5 行使用AndWait 方法。第 5 行之后的所有行都不会执行,侦听器 3 也不会执行。一旦 AndWait 结束其余行,侦听器 3 将被调用
    【解决方案2】:

    使用syncronized 将阻止该方法的并发执行,但实际上会通过强制线程等待任何当前执行来排队发出的请求。

    在处理这种情况时,您可能希望通过在第一次按下按钮后的一段时间内阻止用户交互或在结果计算期间通过禁用按钮并重新启用它来消除按钮单击的抖动

    【讨论】:

    • 感谢您的回答,但我否决了它,因为它是一个不针对代号一的一般答案,它可能会造成混淆。
    猜你喜欢
    • 2022-12-19
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多