Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Synchronization when collecting data from the EDT?

230 views
Skip to first unread message

Knute Johnson

unread,
Jun 4, 2011, 8:38:12 PM6/4/11
to
If you want to remove some data from the EDT and use it in another
thread, does EventQueue.invokeLater() or invokeAndWait() constitute
happens before? I don't think it does, so in that case, if you need to
access some data from your GUI components and use that data on another
thread there has to be some synchronization.

Object obj = new Object(); // use for lock
String str;

EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized (obj) {
str = someJTextField.getText();
}
}
});

// execution should stop here until the EDT releases the lock on obj

synchronized (obj) {
// str should be visible and current here
System.out.println(str);
}

I originally thought that it would be better to use invokeAndWait() to
go get the data but after some research it appears that if the
Runnable() throws an Exception or if the current thread is interrupted,
execution of the current thread will continue. Also the Runnable() will
continue to execute to its end. So it appears that unless you need to
trap exceptions from the Runnable() in the current thread, invokeLater()
is probably a simpler solution.

What do you think about all this?

Thanks,

--

Knute Johnson
s/knute/nospam/

Knute Johnson

unread,
Jun 4, 2011, 8:50:08 PM6/4/11
to
On 06/04/2011 05:38 PM, Knute Johnson wrote:
> If you want to remove some data from the EDT and use it in another
> thread, does EventQueue.invokeLater() or invokeAndWait() constitute
> happens before? I don't think it does, so in that case, if you need to
> access some data from your GUI components and use that data on another
> thread there has to be some synchronization.
>
> Object obj = new Object(); // use for lock
> String str;
>
> EventQueue.invokeLater(new Runnable() {
> public void run() {
> synchronized (obj) {
> str = someJTextField.getText();
> }
> }
> });

Actually I don't think this will work either as the run() method isn't
called until some time later, the subsequent code won't block and the
data won't necessarily have been updated.

So if I use invokeAndWait(), is there any guarantee that an interrupt
won't happen before the run() method is started? An exception shouldn't
be a problem if all the code is contained in a synchronized block.

Daniele Futtorovic

unread,
Jun 5, 2011, 11:52:17 AM6/5/11
to
On 05/06/2011 02:38, Knute Johnson allegedly wrote:
> If you want to remove some data from the EDT and use it in another
> thread, does EventQueue.invokeLater() or invokeAndWait() constitute
> happens before? I don't think it does, so in that case, if you need
> to access some data from your GUI components and use that data on
> another thread there has to be some synchronization.

Knute, sorry for being dense, but I don't quite get how this situation
differs from any other "passing" of data across threads, nor how
#invokeLater() or #invokeAndWait() enter into it as something else than
your regular parallel ("worker" or whatever) thread.

Could you indulge me and shed some light, please?

--
DF.
Determinism trumps correctness.

Knute Johnson

unread,
Jun 5, 2011, 1:47:59 PM6/5/11
to

I don't know that it does, I guess I was hoping that when Sun wrote
invokeLater and AndWait that they assumed that you were getting there
from another thread and put some sort of synchronization in. And maybe
I'm looking for some insight as to how you would do this any other way.
I still think that invokeAndWait has problems if the current thread is
interrupted before execution reaches the synchronized block in the Runnable.

--

Knute Johnson
s/knute/nospam/

Roedy Green

unread,
Jun 5, 2011, 4:39:16 PM6/5/11
to
On Sat, 04 Jun 2011 17:38:12 -0700, Knute Johnson
<nos...@knutejohnson.com> wrote, quoted or indirectly quoted someone
who said :

>If you want to remove some data from the EDT and use it in another
>thread, does EventQueue.invokeLater() or invokeAndWait(

A few thoughts.

1. A few of the Swing methods are inherently thread safe.

2. your invokeLater or event handler could interact with the GUI then
spawn a new background thread to process the data.

3. Usually interaction is spawned by the user -- at an event handler.
--
Roedy Green Canadian Mind Products
http://mindprod.com
How long did it take after the car was invented before owners understood
cars would not work unless you regularly changed the oil and the tires?
We have gone 33 years and still it is rare to uncover a user who
understands computers don't work without regular backups.

markspace

unread,
Jun 5, 2011, 8:46:25 PM6/5/11
to
On 6/4/2011 5:38 PM, Knute Johnson wrote:
> If you want to remove some data from the EDT and use it in another
> thread, does EventQueue.invokeLater() or invokeAndWait() constitute
> happens before? I don't think it does,

Yes and no.

You are correct, SwingUtilities.invokeLater() does NOT specify that it
creates a happens-before relationship. I've griped about this before on
this group. I think it should, because it's almost impossible to use
correctly if it does not.

However, if you look at the implementation, you can see it uses an
Executor to hand off your runnable to the EDT. And the Executor method
invoked does, in fact, specify a happens before relationship. And I
can't think of any way to hand off one object (the runnable) to another
thread with out creating a happens-before relationship. So as a
practical matter, I think you must be ok if you don't synchronize yourself.

If feel you must synchronzie (and I don't disagree), the easiest way
might be to just create a volatile field in the Runnable and let that
synchronize for you.

class MyRunnable implements Runnable {
public volatile int synch;
public void run() {
synch++; // read synch
// do stuff here...

}
}
...
MyRunnable run = new MyRunnable();
run.synch = 42;
SwingUtilities.invokeLater( run );
...

This is the best I think I can do.

John B. Matthews

unread,
Jun 5, 2011, 11:47:41 PM6/5/11
to
In article <8jPGp.40014$Vp.1...@newsfe14.iad>,
Knute Johnson <nos...@knutejohnson.com> wrote:

Focusing on invokeAndWait() [1], I understood it to be the standard way
to wait for data to arrive on the EDT. In particular, it promises to
block until the supplied Runnable's run method has been called on the
EDT. I don't understand why the Runnable needs a synchronized block.

A widely used implementation queues the Runnable and waits [2], using a
private AWTInvocationLock. The Runnable, wrapped in an InvocationEvent,
is subsequently dispatched [3]. When finished, the same
AWTInvocationLock is used to notifyAll().

Of the ways a thread can exit wait() [4], an InterruptedException
appears to be the only one to worry about. It looks like
InvocationEvent is always set to catch Throwable, so you'll have to
catch InvocationTargetException, too. Finally, invokeAndWait() doesn't
call wait() in a loop, as recommended [4]; but I don't think the
calling thread cares if it's not scheduled immediately on waking [5].

Having said that, I see that the Swing tutorial no longer uses
invokeAndWait() in this context. Instead, it focuses on SwingWorker
[6], which can be launched from any thread.

[1]<http://download.oracle.com/javase/6/docs/api/java/awt/EventQueue.html>
[2]<http://kickjava.com/src/java/awt/EventQueue.java.htm>
[3]<http://kickjava.com/src/java/awt/event/InvocationEvent.java.htm>
[4]<http://download.oracle.com/javase/6/docs/api/java/lang/Object.html>
[5]<http://stackoverflow.com/questions/1461913>
[6]<http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html>
[7]<http://stackoverflow.com/questions/4637725>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Knute Johnson

unread,
Jun 6, 2011, 1:11:15 AM6/6/11
to
On 06/05/2011 08:47 PM, John B. Matthews wrote:
>> I don't know that it does, I guess I was hoping that when Sun wrote
>> invokeLater and AndWait that they assumed that you were getting there
>> from another thread and put some sort of synchronization in. And
>> maybe I'm looking for some insight as to how you would do this any
>> other way. I still think that invokeAndWait has problems if the
>> current thread is interrupted before execution reaches the
>> synchronized block in the Runnable.
>
> Focusing on invokeAndWait() [1], I understood it to be the standard way
> to wait for data to arrive on the EDT. In particular, it promises to
> block until the supplied Runnable's run method has been called on the
> EDT. I don't understand why the Runnable needs a synchronized block.

The problem with using invokeAndWait() is that it won't block if the
thread is interrupted and it won't start the Runnable() either.

The synchronized block is to make sure that the data retrieved from the
GUI elements on the EDT were visible to the current thread. I've come
up with what I think is a better way for the project I'm working on and
that is to use a Semaphore.

Semaphore sem = new Semaphore(1);
.
.
while (true) {
try {
sem.acquire();


EventQueue.invokeLater(new Runnable() {
public void run() {

// read data from GUI elements
sem.release();
}
});

sem.acquire(); // blocks here until done above
// do stuff with the GUI element data

} catch (InterruptedException ie) {
// skip the do stuff if interrupted
} finally {
sem.release();
}
}


> A widely used implementation queues the Runnable and waits [2], using a
> private AWTInvocationLock. The Runnable, wrapped in an InvocationEvent,
> is subsequently dispatched [3]. When finished, the same
> AWTInvocationLock is used to notifyAll().
>
> Of the ways a thread can exit wait() [4], an InterruptedException
> appears to be the only one to worry about. It looks like
> InvocationEvent is always set to catch Throwable, so you'll have to
> catch InvocationTargetException, too. Finally, invokeAndWait() doesn't
> call wait() in a loop, as recommended [4]; but I don't think the
> calling thread cares if it's not scheduled immediately on waking [5].

The InvocationTargetException can't be thrown unless something in the
Runnable throws it, so I don't think that is as big a problem as the
interrupted thread issue.

> Having said that, I see that the Swing tutorial no longer uses
> invokeAndWait() in this context. Instead, it focuses on SwingWorker
> [6], which can be launched from any thread.

I didn't use a SwingWorker because it's really set up to be a self
terminating thing and I need to continually update data from my GUI
elements to current thread and the SwingWorker goes the other way, do
something on the current thread and publish it on the EDT.

So John, back to your question about the synchronized block, how would
you get data from the EDT to your current thread without some sort of
synchronization?

--

Knute Johnson
s/knute/nospam/

Knute Johnson

unread,
Jun 6, 2011, 1:17:19 AM6/6/11
to
On 06/05/2011 01:39 PM, Roedy Green wrote:
> On Sat, 04 Jun 2011 17:38:12 -0700, Knute Johnson
> <nos...@knutejohnson.com> wrote, quoted or indirectly quoted someone
> who said :
>
>> If you want to remove some data from the EDT and use it in another
>> thread, does EventQueue.invokeLater() or invokeAndWait(
>
> A few thoughts.
>
> 1. A few of the Swing methods are inherently thread safe.

In the current version of the docs, JTextComponent.getText() is no
longer marked as thread safe.

> 2. your invokeLater or event handler could interact with the GUI then
> spawn a new background thread to process the data.

That's sort of backwards from the way I need to do it. I have a running
thread that needs to collect data from some GUI components, process it
and send it along.

> 3. Usually interaction is spawned by the user -- at an event handler.

And usually in that instance in the invokeLater Runnable you get some
data from your GUI and start a new thread to process them. Starting a
new thread, guarantees "happens before".

Knute Johnson

unread,
Jun 6, 2011, 1:41:49 AM6/6/11
to

volatile int sync;

// in the current thread
// do something you want visible on the EDT

++sync; // write

EventQueue.invokeLater(new Runnable() {
public void run() {

++sync; // read
// the something is now visible here on EDT

I think that would work too.

--

Knute Johnson
s/knute/nospam/

Daniele Futtorovic

unread,
Jun 6, 2011, 8:31:48 AM6/6/11
to
On 06/06/2011 07:11, Knute Johnson allegedly wrote:
> On 06/05/2011 08:47 PM, John B. Matthews wrote:
>> Focusing on invokeAndWait() [1], I understood it to be the standard way
>> to wait for data to arrive on the EDT. In particular, it promises to
>> block until the supplied Runnable's run method has been called on the
>> EDT. I don't understand why the Runnable needs a synchronized block.
>
> The problem with using invokeAndWait() is that it won't block if the
> thread is interrupted and it won't start the Runnable() either.

Isn't that pretty much how it should be? Why should it gobble that
information? If you explicitly want to ignore the interrupted status of
your current thread, you can always throw a Thread#interrupted() in the mix.

Daniele Futtorovic

unread,
Jun 6, 2011, 8:35:49 AM6/6/11
to

How about a BlockingQueue? More overhead, but makes the intent clearer.
Or a java.util.concurrent.Exchanger.

John B. Matthews

unread,
Jun 6, 2011, 11:03:33 PM6/6/11
to
In article <TjZGp.40183$Vp.2...@newsfe14.iad>,
Knute Johnson <nos...@knutejohnson.com> wrote:

> On 06/05/2011 08:47 PM, John B. Matthews wrote:

[...]


> > Focusing on invokeAndWait() [1], I understood it to be the standard
> > way to wait for data to arrive on the EDT. In particular, it
> > promises to block until the supplied Runnable's run method has been
> > called on the EDT. I don't understand why the Runnable needs a
> > synchronized block.
>
> The problem with using invokeAndWait() is that it won't block if the
> thread is interrupted and it won't start the Runnable() either.

The InvocationEvent is posted to the event queue and the calling thread
immediately enters wait(). It's up to the AWT event thread to dispatch
the enclosed Runnable.

> The synchronized block is to make sure that the data retrieved from the
> GUI elements on the EDT were visible to the current thread.

Both invokeAndWait() (on the calling thread) and dispatch() (on the EDT)
synchronize on the (private) AWTInvocationLock.

> I've come up with what I think is a better way for the project I'm
> working on and that is to use a Semaphore.
>

> Semaphore sem = new Semaphore(1); [...]

This looks appealing; it reminds me of DF's suggestion of Exchanger.

[...]

> So John, back to your question about the synchronized block, how
> would you get data from the EDT to your current thread without some
> sort of synchronization?

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."

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

/** @author John B. Matthews */
public class TwoTimer extends JPanel {

private Timer timer = new Timer(10, null);
private int value;

public TwoTimer() {
final JLabel label = new JLabel("0");
timer.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
label.setText(String.valueOf(value++));
}
});
this.add(label);
}

public int getValue() {
return value;
}

public void startSwingTimer() {
timer.start();
}

public void startUtilTimer() {
final LinkedList<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());
}
});
} catch (InterruptedException ex) {
ex.printStackTrace(System.err);
} catch (InvocationTargetException ex) {
ex.printStackTrace(System.err);
}
System.out.println(samples.getLast());
}
}, 1000, 1000);

}

private void display() {
JFrame f = new JFrame("TwoTimer");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
TwoTimer tt = new TwoTimer();
tt.display();
tt.startSwingTimer();
tt.startUtilTimer();
}
});

Daniele Futtorovic

unread,
Jun 7, 2011, 12:51:10 PM6/7/11
to

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.

Also, the println(queue.getLast()) statement probably ought to go into
the try/catch block, lest you want to risk a NoSuchElementException.

John B. Matthews

unread,
Jun 7, 2011, 1:38:29 PM6/7/11
to
In article <islktt$kt1$1...@dont-email.me>,
Daniele Futtorovic <da.fut...@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.

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()?

> Also, the println(queue.getLast()) statement probably ought to go into
> the try/catch block, lest you want to risk a NoSuchElementException.

D'oh, I carelessly moved it out of the block before posting. Thanks.

markspace

unread,
Jun 7, 2011, 5:51:35 PM6/7/11
to
On 6/5/2011 10:17 PM, Knute Johnson wrote:

> On 06/05/2011 01:39 PM, Roedy Green wrote:
>> 2. your invokeLater or event handler could interact with the GUI then
>> spawn a new background thread to process the data.

> That's sort of backwards from the way I need to do it. I have a running
> thread that needs to collect data from some GUI components, process it
> and send it along.

I think Roedy is right. You can invokeLater (or invokeAndWait) and then
in that Runnable kick off a new process.

I guess the main question would be "send it along" where? It might make
a difference. Send it back to the caller or send it elsewhere?

Daniele Futtorovic

unread,
Jun 7, 2011, 6:10:56 PM6/7/11
to
On 07/06/2011 19:38, John B. Matthews allegedly wrote:
> In article <islktt$kt1$1...@dont-email.me>,
> Daniele Futtorovic <da.fut...@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! :)

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.
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?


> 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?

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.

John B. Matthews

unread,
Jun 7, 2011, 11:51:56 PM6/7/11
to
In article <ism7lg$ku1$1...@dont-email.me>,
Daniele Futtorovic <da.fut...@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.fut...@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.

markspace

unread,
Jun 8, 2011, 2:31:35 AM6/8/11
to
On 6/7/2011 3:10 PM, Daniele Futtorovic wrote:

> 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?


Final fields and all data "read through" are only guaranteed for the
final fields themselves. I believe all other synchronization is
guaranteed to be a "full flush" (all previous writes made visible). Off
the top of my head, those:

1. Init static variables.
2. Write to volatile.
3. Synchronize keyword.
4. Thread.start().
5. Thread.join() or Thread.isAlive().
6. Thread.interrupt then Thread.interrupted, Thread.isInterrupted or
seeing InterruptedException.
7. Object.wait() unlock/lock works the same as synchronize.

Knute Johnson

unread,
Jun 9, 2011, 2:05:03 AM6/9/11
to

John:

If the AWTInvocationLock is what is used around the wait() then I think
your access to the the LinkedList is adequately synchronized. A problem
could occur if the timer thread is interrupted, then the wait() will not
wait until the run() method is complete and you could find that the
LinkedList is some incomplete or unstable state in the timer thread. I
think the risk is probably fairly small though. And in this case the
outcome is probably not a problem.

The example I had with the Semaphores could have a similar issue. If
the thread was interrupted it would cause the retrieved data to get ignored.

Did you look through the code for invokeLater(), does it have any

Knute Johnson

unread,
Jun 9, 2011, 2:07:50 AM6/9/11
to
On 06/07/2011 10:38 AM, John B. Matthews wrote:
> 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()?

There is a happens before relationship in a blocking queue. Putting an
element in the queue happens before retrieving it from the queue. You
could synchronize that way as well. All actions before placing an
element in the queue in one thread would be visible in another after
removing that element from the queue.

--

Knute Johnson
s/knute/nospam/

John B. Matthews

unread,
Jun 9, 2011, 2:35:38 PM6/9/11
to
In article <RnZHp.2348$5v5...@newsfe11.iad>,
Knute Johnson <nos...@knutejohnson.com> wrote:

> Did you look through the code for invokeLater(), does it have any
> synchronization?

It's not the same wait-notify synchronization that invokeAndWait() [1]
enjoys. Inside invokeLater() [1], the InvocationEvent [2] receives a
null AWTInvocationLock, which dispatch() later checks and ignores.

public static void invokeLater(Runnable runnable) {
Toolkit.getEventQueue().postEvent(
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
}

Because postEvent() is synchronized on the EventQueue object itself,
you _do_ get the ordering promised in the EventQueue API, i.e. two
Runnables execute in the same order as they are enqueued.

[1]<http://download.oracle.com/javase/6/docs/api/java/awt/EventQueue.html>
[2]<http://download.oracle.com/javase/6/docs/api/java/awt/event/InvocationEvent.html>

John B. Matthews

unread,
Jun 9, 2011, 6:35:08 PM6/9/11
to
In article <rqZHp.2350$5v5...@newsfe11.iad>,
Knute Johnson <nos...@knutejohnson.com> wrote:

Agreed. In the variation below, a LinkedBlockingQueue would allow one to
schedule a sample on the EDT via invokeLater().

public void startUtilTimer() {
final Queue<Integer> samples = new LinkedBlockingQueue<Integer>();


java.util.Timer sampler = new java.util.Timer();
sampler.scheduleAtFixedRate(new TimerTask() {

@Override
public void run() {
while (samples.size() > 5) {
samples.remove();
System.out.println(samples);
}
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
samples.add(getValue());
}
});
}
}, 1000, 1000);
}

Compare to the invokeAndWait() variation:

<https://groups.google.com/d/msg/comp.lang.java.gui/sWKy5Oo8s3E/xaGY8-VoMKYJ>

Daniele Futtorovic

unread,
Jun 9, 2011, 7:17:13 PM6/9/11
to
On 08/06/2011 05:51, John B. Matthews allegedly wrote:
> Yes, I'm arguing that invokeAndWait() alone is sufficient, but I'd
> welcome an alternative using java.util.concurrent.

John, markspace, thanks for shedding some light. One remark though,
John, the JLS section you quoted pertains to final fields. In your
example, the LinkedList wasn't a field.

I believe the following section of the java.util.concurrent package doc
you referred to, to wit "Memory Consistency Properties", encompasses the
point you've been arguing around:
"An unlock (synchronized block or method exit) of a monitor
happens-before every subsequent lock (synchronized block or method
entry) of that same monitor. And because the happens-before relation is
transitive, all actions of a thread prior to unlocking happen-before all
actions subsequent to any thread locking that monitor."

I believe this means that the grabbing, off the EDT, of data produced in
a Runnable passed to #invokeAndWait() will work if, and only if, after
the Runnable is executed, the EDT locks on the same monitor that the
thread calling #invokeAndWait() is waiting on. And I suppose the problem
is that while the code does it this way, the API doesn't specify it (or
does it?). At the same time, I'm having a hard time trying to imagine
how that could possibly *not* be the case. Anyone willing to give it a go?

-.-

As for an alternative, I would humbly submit the following:

static <V> V invokeAndWait( final Callable<V> callable )
throws InterruptedException
{
final Exchanger<V> x = new Exchanger<V>();
EventQueue.invokeLater(


new Runnable(){ @Override public void run() {

try {
x.exchange( callable.call() );
}
catch (InterruptedException iex ){
Thread.currentThread().interrupt();
}
catch ( Exception e ){
//exception in the callable. Blow shit up.
throw new RuntimeException(e);
}
}}
);

return x.exchange( null );
}

static void invokeAndWait( final Runnable ron, long timeout, TimeUnit unit )
throws InterruptedException
{
final CountDownLatch l = new CountDownLatch(1);
EventQueue.invokeLater(


new Runnable(){ @Override public void run() {

ron.run();
l.countDown();
}}
);

l.await( timeout, unit );
}


Daniele Futtorovic

unread,
Jun 9, 2011, 7:25:58 PM6/9/11
to
On 10/06/2011 01:17, Daniele Futtorovic allegedly wrote:
> static <V> V invokeAndWait( final Callable<V> callable )
> throws InterruptedException
> {
> final Exchanger<V> x = new Exchanger<V>();
> EventQueue.invokeLater(
> new Runnable(){ @Override public void run() {
> try {
> x.exchange( callable.call() );
> }
> catch (InterruptedException iex ){
> Thread.currentThread().interrupt();
> }
> catch ( Exception e ){
> //exception in the callable. Blow shit up.
> throw new RuntimeException(e);
> }
> }}
> );
>
> return x.exchange( null );
> }

Realised one big mistake: the caller might block indefinitely.

Corrected version:

static <V> V invokeAndWait( final Callable<V> callable )
throws InterruptedException
{
final Exchanger<V> x = new Exchanger<V>();
EventQueue.invokeLater(
new Runnable(){ @Override public void run() {
try {
x.exchange( callable.call() );
}
catch (InterruptedException iex ){

//best effort
try { x.exchange( null ); } catch ( InterruptedException
iex2 ){}


Thread.currentThread().interrupt();
}
catch ( Exception e ){
//exception in the callable. Blow shit up.

try {
x.exchange( null );
throw new RuntimeException(e);
}
catch ( InterruptedException iex2 ){
Thread.currentThread().interrupt();

John B. Matthews

unread,
Jun 9, 2011, 10:34:35 PM6/9/11
to
In article <isrk9n$f4l$1...@dont-email.me>,
Daniele Futtorovic <da.fut...@laposte-dot-net.invalid> wrote:

> One remark though, John, the JLS section you quoted pertains to final
> fields. In your example, the LinkedList wasn't a field.

Quite right; thanks for catching that. §17.5 Final Field Semantics does
not apply to local variables. In my example, the local variable samples
is final in order to access it from the anonymous inner class that
implements Runnable. I should have cited §8.1.3:

<Mhttp://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3>

"Any local variable ... used but not declared in an inner class must be
declared final."

[I'm not ignoring your example; I just wanted to redress my error.]

Daniele Futtorovic

unread,
Jun 9, 2011, 11:22:52 PM6/9/11
to
On 10/06/2011 01:17, Daniele Futtorovic allegedly wrote:
> static void invokeAndWait( final Runnable ron, long timeout, TimeUnit unit )
> throws InterruptedException
> {
> final CountDownLatch l = new CountDownLatch(1);
> EventQueue.invokeLater(
> new Runnable(){ @Override public void run() {
> ron.run();
> l.countDown();
> }}
> );
>
> l.await( timeout, unit );
> }

Sigh. Same mistake here.

static void invokeAndWait( final Runnable ron, long timeout, TimeUnit unit )
throws InterruptedException
{
final CountDownLatch l = new CountDownLatch(1);
EventQueue.invokeLater(
new Runnable(){ @Override public void run() {

try {
ron.run();
}
finally {

markspace

unread,
Jun 10, 2011, 11:04:04 AM6/10/11
to
On 6/9/2011 4:17 PM, Daniele Futtorovic wrote:


> a Runnable passed to #invokeAndWait() will work if, and only if, after
> the Runnable is executed, the EDT locks on the same monitor that the
> thread calling #invokeAndWait() is waiting on. And I suppose the problem
> is that while the code does it this way, the API doesn't specify it (or
> does it?). At the same time, I'm having a hard time trying to imagine
> how that could possibly *not* be the case. Anyone willing to give it a go?


This is the same conclusion I came to. I don't see how Oracle can
implement invokeLater without using synchronization. They have to pass
the Runnable from your thread to the EDT, and the fields used to do that
must be synchronized somehow.

And yet their API does not specify that invokeLater does provide any
happens-before semantics, which forces a large and silly burden on the
user of making yet another synchronization mechanism on top of the
existing one. Or the large and silly burden of ignoring the docs and
coding to the implementation.

I really wish they'd just add the happens-before semantics to their docs
and be done with it. It's kind of a waste of everybody's time not to.

John B. Matthews

unread,
Jun 10, 2011, 9:13:36 PM6/10/11
to

I see that the EventQueue says, "The only requirements are that
events...are dispatched...in the same order as they are enqueued." It's
not quite as cogent as the "happens-before" of java.util.concurrent [2]
and the JLS.

> It's kind of a waste of everybody's time not to.

Agreed. I enjoyed studying the implementations, and I appreciate everyone's
critical analysis.

[1]<http://download.oracle.com/javase/6/docs/api/java/awt/EventQueue.html>
[2]<http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html>

Knute Johnson

unread,
Jun 12, 2011, 3:45:47 PM6/12/11
to
On 06/09/2011 03:35 PM, John B. Matthews wrote:
> Agreed. In the variation below, a LinkedBlockingQueue would allow one to
> schedule a sample on the EDT via invokeLater().

That may be the smartest idea yet and simplest too. Send off a call to
invokeLater() and in the following code wait until the retrieved data
has been put into the BlockingQueue. If there is a problem getting the
data in the invokeLater() call, interrupt the calling thread and try
again. That would necessitate having a reference to the thread
available but that would be OK I think.

--

Knute Johnson
s/knute/nospam/

Knute Johnson

unread,
Jun 12, 2011, 3:51:41 PM6/12/11
to
On 06/09/2011 04:17 PM, Daniele Futtorovic wrote:
> On 08/06/2011 05:51, John B. Matthews allegedly wrote:
>> Yes, I'm arguing that invokeAndWait() alone is sufficient, but I'd
>> welcome an alternative using java.util.concurrent.
>
> John, markspace, thanks for shedding some light. One remark though,
> John, the JLS section you quoted pertains to final fields. In your
> example, the LinkedList wasn't a field.
>
> I believe the following section of the java.util.concurrent package doc
> you referred to, to wit "Memory Consistency Properties", encompasses the
> point you've been arguing around:
> "An unlock (synchronized block or method exit) of a monitor
> happens-before every subsequent lock (synchronized block or method
> entry) of that same monitor. And because the happens-before relation is
> transitive, all actions of a thread prior to unlocking happen-before all
> actions subsequent to any thread locking that monitor."
>
> I believe this means that the grabbing, off the EDT, of data produced in
> a Runnable passed to #invokeAndWait() will work if, and only if, after
> the Runnable is executed, the EDT locks on the same monitor that the
> thread calling #invokeAndWait() is waiting on. And I suppose the problem
> is that while the code does it this way, the API doesn't specify it (or
> does it?). At the same time, I'm having a hard time trying to imagine
> how that could possibly *not* be the case. Anyone willing to give it a go?

That would work both ways too. If you wanted data visible in the run()
method of an invoke... then you would need to synchronize your changes
to the data before calling or if you were retrieving something from the
invoke... calls, syncrhonize after it returns. I'm not sure why the
docs don't publish the details about the AWTInvocationLock. I would
think that would make this less confusing. Maybe though they don't want
you blocking their thread?

--

Knute Johnson
s/knute/nospam/

0 new messages