这与我问的早期question有关,答案是:
如果一个字段被多个访问 线程,它应该是易变的或 最终,或仅访问 同步块。除此以外, 分配的值可能不可见 其他线程。
此外,操作屏幕上像素的任何内容都应该从event dispatch thread运行,尽管使用重绘/绘画时这是透明处理的。
因此,根据我的理解,我们需要担心内存模型,就像在屏幕上移动的精灵动画一样简单。
我的问题是,这种理解是否正确,并且Sun教程示例例如TumbleItem(source)不正确?
答案 0 :(得分:1)
典型地:
在步骤(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组件做任何事情,所以我不认为这是一个问题,但是我不是专家。