Event Dispatch Thread meets the Java Memory Model

583 views Asked by At

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?

4

There are 4 answers

3
Stephen C On BEST ANSWER

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.

1
camickr On

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.

0
irreputable On

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.

0
TofuBeer On

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 :-).