【问题标题】:Event Dispatch Thread meets the Java Memory Model事件调度线程符合 Java 内存模型
【发布时间】:2009-12-05 20:43:20
【问题描述】:

这与我之前问过的question有关,答案是:

如果一个字段被多个访问 线程,它应该是 volatile 或 最终的,或仅使用 同步块。除此以外, 分配的值可能不可见 其他线程。

此外,任何在屏幕上操作像素的东西都应该从event dispatch thread 运行,尽管当您使用重绘/绘画时这是透明地处理的。

因此,据我了解,对于像精灵在屏幕上移动的动画这样简单的东西,我们需要担心内存模型。

我的问题是,这种理解是否正确,而 Sun 教程示例例如 TumbleItem (source) 不正确?

【问题讨论】:

    标签: java multithreading edt java-memory-model


    【解决方案1】:

    你知道,我想你在这里可能有一点。 TumbleItem 代码使用worker.isDone() 来查明工作是否已经完成。但是,我认为这不会导致完全“同步”。

    我对 JDK 1.6 代码的解读是 SwingWorker.isDone() 使用 FutureTask ,而 FutureTask 又使用带有易失性 state 属性的 Sync 对象。 isDone() 的执行路径似乎不涉及 synchronized 方法或块。

    我不是新并发类的真正专家,但我认为 TumbleItem 应该在某些时候调用 worker.get() 以保证正确同步。

    编辑:我指的是 EDT 使用由工作人员填充的 img 数组。但是,正如@The Feast 所指出的,EDT 使用初始化参数似乎也存在问题。

    【讨论】:

    • 我认为如果该示例使用原子整数等,它将起作用。不过,我看不到任何教程(Sun 或其他)上特别讨论过这个问题。
    • volatile 和同步的记忆效果一样。
    • 但仅在 volatile 变量上,而不是在所有其他变量上...我理解。
    【解决方案2】:

    通常:

    1. 工作线程进行一些计算并得出一些结果。
    2. 它在事件队列中插入一个事件
    3. 事件线程检索事件并处理它
    4. 在此过程中会访问结果。

    已在步骤 (2) 和 (3) 中完成了正确的同步。这就是为什么步骤(1)中的结果可以在步骤(4)中看到的原因。想想你将如何实现事件队列,你会看到的。

    【讨论】:

      【解决方案3】:

      您可以使用ThreadCheckingRepaintManager 来帮助您找到违反 EDT 部分的时间(不是直接回答您的问题,但仍然很有帮助 :-)。

      【讨论】:

        【解决方案4】:

        我不确定你说 Sun 教程不正确是什么意思?

        动画是通过使用 Swing Timer 完成的。当 Timer 触发时,代码在 EDT 上执行,这意味着它遵循 Swing 指南。

        编辑:

        是的,您的理解是正确的,从技术上讲,您应该担心内存模型。

        是的,“偏移量”在技术上在两个不同的线程中更新:

        a) 加载小程序时的默认线程

        b) EDT“一旦”动画开始。

        但是在我看来(我可能倾向于简化事情),当加载小程序时,代码在单个线程上执行,而正在发生的只是偏移值正在被初始化。由于只有一个线程在运行,因此您不必担心它会同时从多个线程更新。

        现在,一旦动画开始,我们就会遇到不同的情况,因为 GUI 使用此值来控制动画,因此只能由 EDT 上的代码更新。

        教程说“应该在事件调度线程上创建、查询和操作 Swing 组件”,但我们还没有开始对 Swing 组件做任何事情,所以我认为这不是问题,但是我不是线程专家。

        【讨论】:

        • offset 例如被多个线程修改。我同意它不违反任何 EDT 准则。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-06
        • 2011-11-11
        相关资源
        最近更新 更多