Problemas con la sincronización dentro del hilo de despacho de eventos

Estaba trabajando con java.net.Authenticator para crear un cuadro de diálogo de bloqueo que solicita el inicio de sesión / contraseña del proxy al usuario la primera vez que se establece una conexión a través del proxy. Authenticator funciona bien, pero tuve un problema extraño cuando intenté sincronizar el método que muestra el diálogo de entrada.

Aquí hay un ejemplo de código de trabajo abstracto del problema que encontré:

private static JFrame frame;

public static void main ( String[] args )
{
    frame = new JFrame ( "Frame" );
    frame.add ( new JLabel ( "This is main application" ) );
    frame.setSize ( 500, 500 );
    frame.setLocationRelativeTo ( null );
    frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
    frame.setVisible ( true );

    // Cycling thread
    new Thread ( new Runnable ()
    {
        public void run ()
        {
            while ( true )
            {
                // Opening new dialog in a separate event dispatch thread
                SwingUtilities.invokeLater ( new Runnable ()
                {
                    public void run ()
                    {
                        showSomeLockingDialog ();
                    }
                } );

                // Wait 3 seconds before next window
                try
                {
                    Thread.sleep ( 3000 );
                }
                catch ( InterruptedException e )
                {
                    e.printStackTrace ();
                }
            }
        }
    } ).start ();
}

private static final Object lock = new Object ();

private static void showSomeLockingDialog ()
{
    synchronized ( lock )
    {
        // Output to see that this method is not finished yet
        System.out.println ( "Method start" );

        // Modal thread-blocking dialog
        JDialog dialog = new JDialog ( frame, "Lock" );
        dialog.add ( new JLabel ( "This should be blocking other dialogs" ) );
        dialog.pack ();
        dialog.setLocationRelativeTo ( null );
        dialog.setModal ( true );
        dialog.setVisible ( true );

        // Output to see that this method is not finished yet
        System.out.println ( "Method end" );
    }
}

Así que básicamente:

  1. Hay un marco principal visible (en realidad, solo para mantener JVM funcionando)
  2. Hay un subproceso de ciclo que solicita el método showSomeLockingDialog () en cada ciclo
  3. El método está sincronizado en el objeto "bloqueo"
  4. Hay salida de consola al inicio y al final del método

Entonces, si ejecuta este ejemplo, verá que aparece un nuevo cuadro de diálogo ignorando la sincronización, incluso si no cierra el cuadro de diálogo anterior. También probé la sincronización de métodos simples, pero tiene el mismo efecto.

Todo cambia si cambiamos un poco la forma en que llamamos showSomeLockingDialog ():

    new Thread ( new Runnable ()
    {
        public void run ()
        {
            showSomeLockingDialog ();
        }
    } ).start ();

(solo usando un hilo separado en lugar de llamar al método dentro del hilo de despacho de eventos)

De esta manera, todo funciona de la forma en que espero que funcione: las nuevas llamadas de diálogo se bloquean hasta que se cierre la llamada anterior.

Y eso es bastante extraño: ¿qué tiene de especial el subproceso de envío de eventos que se ignora la sincronización?

O si en realidad es un error, ¿hay alguna solución? Tal vez me estoy perdiendo algo enorme ...

Algunas reflexiones: me parece que el método setVisible de diálogo modal actúa de manera diferente dentro del hilo de despacho de eventos (de lo contrario, bloquearía toda la interfaz si se llama desde allí). Pero, ¿cómo afecta eso a la sincronización ...

PD Y no, no puedo usar el segundo ejemplo (de trabajo) en mi caso específico, porque no estoy llamando a ese método donde quiero, se llama desde un lugar aleatorio, principalmente desde clases JDK estándar (cuando cualquier recurso que sea cargarse desde Internet, ya sea imagen en JLabel, alguna secuencia de entrada de URL o cualquier otra cosa).

Respuesta 1

Ok, este está aturdiendo mi pequeña mente. Recibo un retorno nulo de una de las dos llamadas a GetObjectField (). Cada objeto es un DirectByteBuffer. La llamada no arroja una excepción por no encontrar el ...

Tengo tres elementos A, B y C. Quería crear un XSD para el cual el esquema debería ser la elección de [A] o [B y C] o [A y B y C] ¿Alguien puede ayudarme a crear un xsd ...

¿Cómo accedería a una imagen en una carpeta diferente en Java? Tengo una serie de imágenes y cambian según la entrada del usuario, que es para lo que sirve x. picture.setIcon (nuevo ImageIcon ("\\ resources \\ icons \\ ...

Mi programa funciona pero no de la manera que quiero. Esta es la salida que quiero: C: \ Documents and Settings \ Joe King \ My Documents \ 418.85A Java \ Projects \ Day 6> java Project3 nina pinta "santa maria" ...