La salida de Java MultiThreading aparentemente ambigua en el sistema seguro para subprocesos.

Aquí está mi código:

class Question extends Thread    {
    static String info;

    public Question(String info )    {
        this.info = info;
    }
    private void inProtected () {
        synchronized ( info )       {
            System.out.println("--> " + info +  " Hi");
            System.out.println("<-- " + info +  " Hi");
        }
    }

    public void run () {
        inProtected();
    }
    public static void main (String args []) {
        new Question("a").start();
        try {
            sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Question("ab").start();

    }
}

Este código produce a veces, una salida como esta:

--> ab Hi
--> a Hi //Wait a second, what? How can "a" print after "ab"?
<-- ab Hi
<-- ab Hi

He visto el código de System.out y varias respuestas en StackOverflow y sé con certeza que System.out es seguro para subprocesos. Entonces, ¿cómo es posible este orden de ejecución, dado que infoes estático y el hilo principal crea los dos hilos (con "a" y "ab") en orden?

Editar: Soy perfectamente consciente de que el método inProtected no está sincronizado ya que el valor es cambiado por los diferentes hilos. Mi pregunta es, ¿cómo es posible que "a" se imprima después de "ab", ya que el hilo principal crea los hilos en orden, lo que en consecuencia modifica la información de la variable estática?

Respuesta 1

Estoy leyendo datos de la base de datos vertica usando múltiples hilos en java. Tengo alrededor de 20 millones de registros y estoy abriendo 5 subprocesos diferentes que tienen consultas seleccionadas como esta ... start = threadnum; ...

Tengo problemas para descubrir cómo encontrar la aparición de los números dentro de una matriz 2D. Soy nuevo en Java, así que tengo que hacer este programa sin usar mapas / soluciones avanzadas. Ejemplo: dado ...

Un ejemplo rápido es una colección del nombre y apellido de los usuarios. Un método requiere que compare usando el primer nombre, otro usando el apellido. ¿Es posible tener dos compareTo () diferentes? ...

Cómo crear esto: JButton b = new JButton ("text"). AddActionListener (e -> classX.addNewTest ())); botones.add (b); en una linea? Intenté esto: panel.add (b = new JButton ("text"). AddActionListener (e ...