Event Dispatch Thread符合Java Memory Model

时间:2009-12-05 20:43:21

标签: java multithreading edt java-memory-model

这与我问的早期question有关,答案是:

  

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

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

因此,根据我的理解,我们需要担心内存模型,就像在屏幕上移动的精灵动画一样简单。

我的问题是,这种理解是否正确,并且Sun教程示例例如TumbleItemsource)不正确?

4 个答案:

答案 0 :(得分:1)

典型地:

  1. 工作线程进行一些计算并得出一些结果。
  2. 它在事件队列中插入一个事件
  3. 事件线程检索事件并处理它
  4. 在此过程中访问结果。
  5. 在步骤(2)和(3)中进行了适当的同步。这就是步骤(1)中的结果在步骤(4)中可见的原因。想一想如何实现事件队列,你会看到。

答案 1 :(得分:1)

您可以使用ThreadCheckingRepaintManager来帮助您查找违反EDT部分的内容(不是您问题的直接答案,但有用的是: - )。

答案 2 :(得分:1)

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

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

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

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

答案 3 :(得分:0)

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

使用Swing Timer完成动画。当Timer触发时,代码在EDT上执行,这意味着它遵循Swing准则。

编辑:

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

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

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

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

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

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

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