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

Re: Outside of the EDT: JOptionPane.showMessageDialog

248 views
Skip to first unread message
Message has been deleted

Knute Johnson

unread,
Dec 27, 2012, 1:03:00 AM12/27/12
to
On 12/26/2012 6:44 PM, Stefan Ram wrote:
> Sometimes, one sees example programs in recent Java books where
> JOptionPane.showMessageDialog or JOptionPane.showInputDialog
> is used outside of the EDT.
>
> So, is this good practice?
>
> On
>
> http://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html
>
> , I do not find remarks about those methods being thread safe.
>

I looked at the source for JOptionPane and I don't see anything in there
that would lead me to believe that you could invoke it safely on other
than the EDT.

--

Knute Johnson
Message has been deleted

John B. Matthews

unread,
Dec 27, 2012, 10:23:47 AM12/27/12
to
In article
<showMessageDialo...@ram.dialup.fu-berlin.de>,
r...@zedat.fu-berlin.de (Stefan Ram) wrote:

> Knute Johnson <nos...@knutejohnson.com> writes:
> > I looked at the source for JOptionPane and I don't see
> > anything in there that would lead me to believe that you
> > could invoke it safely on other than the EDT.
>
> Possibly it's the way they are called, in a sequential
> manner without any callbacks. When the application invokes
> showMessageDialog, there is no Swing component yet, the
> application waits synchronously until after the end of
> execution of showMessageDialog, when again there is no Swing
> component anymore. So, during the runtime of
> showMessageDialog, Swing has exclusive control. Maybe this
> suffices to prevent any problems with multithreading?

I'd say no. If the dialog is not constructed on the EDT, then
it is constructed on some other thread, e.g. the initial
thread. At any point, the construction of a component of the
dialog or the Object(s) referenced in the message parameter may
result in a Runnable being posted to the EDT, which is started
with the first invocation of postEvent(). This results in a
race between the (initial) thread and the EDT. Proving the
absence of a problem for a particular case would have to rely
on (undocumented) implementation details.

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

Knute Johnson

unread,
Dec 27, 2012, 12:06:57 PM12/27/12
to
On 12/27/2012 7:53 AM, Stefan Ram wrote:
> "John B. Matthews" <nos...@nospam.invalid> writes:
>> I'd say no. If the dialog is not constructed on the EDT, then
>
> I the meantime, I also started to see it this way. So, then
>
> public static void main( final java.lang.String args[] )
> { final java.lang.String name = JOptionPane.showInputDialog
> ( "Hi, what's your name?" ); /* ... */ }
>
> is no good idea in a beginner's book (I saw something like
> this in a Java textbook from 2011).
>

I was curious to see if calling JOptionPane.showMessageDialog() would
start the EDT and in fact it does. Below are the AWT-EventQueue-0
thread traces from jconsole. I don't really know what they mean but
they are slightly different depending on whether the call was put on the
EDT.

I'll tell you that I always wrap any calls to JOptionPane.show... in
EventQueue.invokeLater if I'm not already on the EDT. I don't know that
it matters but I can't find any documentation anywhere that says you
don't need to do that.

I think I'm going to go look through the source again and see if I can
find where the EDT gets started.

import javax.swing.*;

public class test6 {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null,"test6");
}
}


Name: AWT-EventQueue-0
State: WAITING on
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@baecb8
Total blocked: 6 Total waited: 8

Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(Unknown Source)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown
Source)
java.awt.EventQueue.getNextEvent(Unknown Source)
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.WaitDispatchSupport$2.run(Unknown Source)
java.awt.event.InvocationEvent.dispatch(Unknown Source)
java.awt.EventQueue.dispatchEventImpl(Unknown Source)
java.awt.EventQueue.access$200(Unknown Source)
java.awt.EventQueue$3.run(Unknown Source)
java.awt.EventQueue$3.run(Unknown Source)
java.security.AccessController.doPrivileged(Native Method)
java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
java.awt.EventQueue.dispatchEvent(Unknown Source)
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.run(Unknown Source)



import java.awt.*;
import javax.swing.*;

public class test6 {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null,"test6");
}
});
}
}


Name: AWT-EventQueue-0
State: WAITING on
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@448192
Total blocked: 3 Total waited: 8

Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(Unknown Source)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown
Source)
java.awt.EventQueue.getNextEvent(Unknown Source)
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.WaitDispatchSupport$2.run(Unknown Source)
java.awt.WaitDispatchSupport$4.run(Unknown Source)
java.security.AccessController.doPrivileged(Native Method)
java.awt.WaitDispatchSupport.enter(Unknown Source)
java.awt.Dialog.show(Unknown Source)
javax.swing.JOptionPane.showOptionDialog(Unknown Source)
javax.swing.JOptionPane.showMessageDialog(Unknown Source)
javax.swing.JOptionPane.showMessageDialog(Unknown Source)
javax.swing.JOptionPane.showMessageDialog(Unknown Source)
test6$1.run(test6.java:8)
java.awt.event.InvocationEvent.dispatch(Unknown Source)
java.awt.EventQueue.dispatchEventImpl(Unknown Source)
java.awt.EventQueue.access$200(Unknown Source)
java.awt.EventQueue$3.run(Unknown Source)
java.awt.EventQueue$3.run(Unknown Source)
java.security.AccessController.doPrivileged(Native Method)
java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
java.awt.EventQueue.dispatchEvent(Unknown Source)
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.run(Unknown Source)


--

Knute Johnson

John B. Matthews

unread,
Dec 27, 2012, 4:16:11 PM12/27/12
to
In article <kbhv7n$iij$1...@dont-email.me>,
Knute Johnson <nos...@knutejohnson.com> wrote:

[Interesting experimental results omitted]

> I think I'm going to go look through the source again and see if I
> can find where the EDT gets started.

In EventQueue, postEvent() calls postEventPrivate(), which
(conditionally) invokes initDispatchThread().

John B. Matthews

unread,
Dec 27, 2012, 4:34:34 PM12/27/12
to
In article <EDT-20121...@ram.dialup.fu-berlin.de>,
r...@zedat.fu-berlin.de (Stefan Ram) wrote:

> "John B. Matthews" <nos...@nospam.invalid> writes:
> >I'd say no. If the dialog is not constructed on the EDT, then
>
> I the meantime, I also started to see it this way. So, then
>
> public static void main( final java.lang.String args[] )
> { final java.lang.String name = JOptionPane.showInputDialog
> ( "Hi, what's your name?" ); /* ... */ }
>
> is no good idea in a beginner's book (I saw something like
> this in a Java textbook from 2011).

I can see this as an introductory example with the footnote,
"The example is incorrect, as we'll learn in chapter _n_."

The Runnable variation might merit a nearby explanation
along these lines:

<http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html>
Message has been deleted

John B. Matthews

unread,
Dec 29, 2012, 10:38:48 AM12/29/12
to
> public class Main
> { public static void main( final java.lang.String[] args )
> { final javax.swing.JFrame frame = new javax.swing.JFrame( "Hallo Swing!" );
> frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE );
> frame.setVisible( true ); }}
>
> It hurts somewhat to see this, but this example appears
> just after the introduction of »new«, and makes the effect
> of »new« visible somehow, so I thought it might be a good
> motivation. In a sense, a JFrame is a »visible object«, so
> this example visualizes objects, which might help to learn.
> But I have not yet introduced interface implementations, and
> so I cannot yet implement java.lang.Runnable.

This seems like a reasonable compromise. When returning to the
topic, the example is simple enough to trace execution and show
that, while a particular implementation may be thread-safe,
there is no general assurance without starting on the EDT. The
didactic problem is complicated by the fact that incorrect
examples rarely fail reliably, and examples that fail reliably
are often so contrived as to to be obviously incorrect.

Lew

unread,
Dec 31, 2012, 3:00:47 PM12/31/12
to
John B. Matthews wrote:
> (Stefan Ram) wrote:
>> public class Main
>> { public static void main( final java.lang.String[] args )
>> { final javax.swing.JFrame frame = new javax.swing.JFrame( "Hallo Swing!" );
>> frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE );
>> frame.setVisible( true ); }}
>
>> It hurts somewhat to see this, but this example appears

For two reasons.

I respect Stefan's knowledge, logic and code, but not his layout.

He's explained his reasons and I accept them. From him.

But don't agree. Like as if it mattered whether I do or not.

Pedagogically his style is useful, as it gives a contrast between
idiosyncratic and conventional styles, and students / interested parties
may make their own determination as to the relative merits.

>> just after the introduction of »new«, and makes the effect
>> of »new« visible somehow, so I thought it might be a good
>> motivation. In a sense, a JFrame is a »visible object«, so
>> this example visualizes objects, which might help to learn.
>> But I have not yet introduced interface implementations, and
>> so I cannot yet implement java.lang.Runnable.

Pedagogical purposes often include introduction of flawed code for a
later twist. I heard an economics professor explain once how "guns and
butter" didn't make actual real-world sense, of course, but was important
to provide common ground and to introduce the terminology and techniques
of economic analysis. Analysis of the limitations of introductory models
is a standard way to grow a student's skills.

> This seems like a reasonable compromise. When returning to the
> topic, the example is simple enough to trace execution and show
> that, while a particular implementation may be thread-safe,

Or you could go with John's more succinct and accessible way of saying
what I just rephrased.

> there is no general assurance without starting on the EDT. The
> didactic problem is complicated by the fact that incorrect
> examples rarely fail reliably, and examples that fail reliably
> are often so contrived as to to be obviously incorrect.

Two great points to bring to young minds' attention early on.

It also helps to introduce the notion of exogenous factors. The point
is that no factor can truly be ruled out as irrelevant. Many threading
bugs, in particular EDT ones and the change of Swing docs to reflect this,
were not recognized until the generalized shift to multiprocessor mobos
in the early oughts. This exposed both the blooms and the thorns of the
foresightful Java concurrency rose garden.

You might think the JVM insulates one from the exigencies of hard hardware.
Turns out you cannot ignore context entirely.

Another good thing to remark during early training.

--
Lew
0 new messages