Re: Synchronization when collecting data from the EDT?
In article <ism7lg$ku1$1@dont-email.me>,
Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> wrote:
On 07/06/2011 19:38, John B. Matthews allegedly wrote:
In article <islktt$kt1$1@dont-email.me>,
Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> wrote:
On 07/06/2011 05:03, John B. Matthews allegedly wrote:
Here's my (contrived) sscce. A javax.swing.Timer increments an
int at 100 Hz, while a java.util.TimerTask samples the value at 1
Hz. I'd like the API to be a little more explicit, but it does
say that the calling thread blocks and the Runnable's dispatch
"will happen after all pending events are processed."
[code elided]
John, is it intended that you didn't use a thread-safe
producer/consumer queue (a mere LinkedList)? I would have thought
one would be necessary, but since it touches upon the subject
Knute brought to our attention, I'm wondering whether there's some
kind of point involved.
I appreciate your insight on this. I'm afraid my example just
recapitulates Knute's question without answering it: Does the
invokeAndWait() API ensure correct synchronization when used as
shown? I'm confident that the _implementation_ I examined is
correct, as the relevant methods are synchronized. Sadly, I have a
tendency to over- read the API.
Aha! So it was the point! :)
Yes, I'm arguing that invokeAndWait() alone is sufficient, but I'd
welcome an alternative using java.util.concurrent.
Question then, for I am not an expert when it comes to the memory
model: You say the implementation you examined guarantees the code's
correctness. This seems to me to imply that the non-EDT thread, upon
calling invokeAndWait(), because it locks and waits on some monitor,
is guaranteed to fetch a fresh copy of the LinkedList instance before
it proceeds to dereference it. Is that actually so? Makes sense I
guess, but I had never thought of it like that.
IIUC, because samples is final, it gets slightly different treatment:
<http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.5>
The reference itself is immutable, and changes to the content are
synchronized by invokeAndWait(). Here's a variation that retains just
the last five samples:
public void startUtilTimer() {
final Queue<Integer> samples = new LinkedList<Integer>();
java.util.Timer sampler = new java.util.Timer();
sampler.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
samples.add(getValue());
}
});
if (samples.size() > 5) {
samples.remove();
}
System.out.println(samples);
} catch (InterruptedException ex) {
ex.printStackTrace(System.err);
} catch (InvocationTargetException ex) {
ex.printStackTrace(System.err);
}
}
}, 1000, 1000);
}
To be more precise, I believe my question boils down to this: when a
thread's memory is flushed, is that always a full flush, or can it be
a selective flush, and if so, how does the selection happen?
IIUC, the memory model uses the notion of a happens-before relationship:
<http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.5
I usually rely on this summary of Memory Consistency Properties:
<http://download.oracle.com/javase/6/docs/api/java/util/concurrent/packag
e-summary.html>
I can't find a Sun/Oracle example using invokeAndWait() dated later
than 2000, well after the advent of java.util.concurrent. Would it
be correct to infer that using, say BlockingQueue, would obviate
the need for invokeAndWait()?
You mean "well before", don't you?
Quite right; thanks.
A BlockingQueue would only be a good solution if the non-EDT thread
is waiting for a value, rather than for a process to finish. But it
would seem to me that Exchanger + CountdownLatch(1) would indeed make
the "AndWait()" part obsolete. Or at least provide a complete
alternative.
Sadly, I lack experience in this area. The critical thing would be not
to block the EDT. I'm thinking a BlockingQueue passed via invokeLater(),
which is _not_ synchronized.
--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>