views:

216

answers:

4

This is related to an earlier question I asked, where the answer was:

If a field is accessed by multiple threads, it should be volatile or final, or accessed only with synchronized blocks. Otherwise, assigned values may not be visible to other threads.

In addition anything that manipulates pixels on screen should be run from the event dispatch thread although this is handled transparently when you use repaint / paint.

Therefore, by my understanding, we need worry about the memory model for something as simple as an animation of a sprite moving across the screen.

My question is, is this understanding correct, and Sun tutorial examples eg TumbleItem (source) incorrect?

A: 

I'm not sure what you mean about the Sun tutorial being incorrect?

The animation is done by using a Swing Timer. When the Timer fires the code is executed on the EDT which means it is following the Swing guidelines.

Edit:

Yes your understanding is correct, technically you should worry about the memory model.

And yes, the "offset" is technically updated in two different threads:

a) the default thread when the applet get loaded

b) the EDT "once" the animation is started.

However in my mind (and I may tend to simplify things), when the applet is loaded code is executing on a single thread and all that is happening is that the offset value is simply being initialized. Since only a single Thread is running you shouldn't have to worry about it being updated from multiple threads at the same time.

Now, once the animation has started we have a different situation as this value is used by the GUI to control the animation and therefore should only ever be updated by code on the EDT.

The tutorial says "Swing components should be created, queried, and manipulated on the event-dispatching thread", but we have not yet started to do anything with the Swing components so I don't think it is a problem, but I am no Thread expert.

camickr
`offset` for example is modified by multiple threads. I agree it doesn't violate any EDT guidelines.
Pool
See edited answer for further comments.
camickr
+1  A: 

typically:

  1. a worker thread does some calculation and reaches some results.
  2. it inserts an event in the event queue
  3. the event thread retrieves the event and process it
  4. during the process the results are accessed.

proper synchronization has been done in step(2) and (3). that's why the results in step(1) can be visible in step(4). Think how you would implement the event queue, and you'll see.

irreputable
+1  A: 

You can use the ThreadCheckingRepaintManager to help you find when you violate the EDT part (not a direct answer to your question, but helpful none the less :-).

TofuBeer
+1  A: 

You know, I think you may have a point here. The TumbleItem code uses worker.isDone() to find out whether the work has been completed. However, I don't think this causes a full "synchronize".

My reading of the JDK 1.6 code is that SwingWorker.isDone() uses FutureTask which in turn uses a Sync object with a volatile state attribute. The execution path for isDone() doesn't seem to involve a synchronized method or block.

I'm not a real expert on the new concurrent classes, but I think the TumbleItem should be calling worker.get() at some point to guarantee proper synchronization.

EDIT: I'm referring to the EDT's use of the img array that is populated by the worker. However, it also appears there is an issue with the EDT's use of the initialization parameters, as noted by @The Feast.

Stephen C
I think if the example used atomic integers etc it would work. I can't see this issue particularly discussed on any tutorial (Sun or otherwise) though.
Pool
`volatile` has the same memory effect as synchronized.
irreputable
But ONLY on the volatile variable not on all others ... or so I understand.
Stephen C