¿Hay alguna optimización para la seguridad de los subprocesos en el bucle de Java?

Kidsunbo:

Tengo un fragmento de código que cambiar un contador de dos hilos. No es hilo de seguridad porque no puse ninguna variable o bloqueo atómica en el código. Se da el resultado correcto como lo esperaba si el código sólo se ejecuta una vez, pero quiero ejecutarlo en varias ocasiones, por lo que poner el código en un bucle. Y la cuestión es que sólo el primero o los dos primeros bucles generará el resultado que esperaba. Para el resto de los bucles, los resultados son siempre 0, lo que parece ser segura hilo. ¿Hay cualquier operador interno en la máquina virtual de Java resultante tal cosa?

He intentado cambiar el número de bucles, y la primera uno o dos son siempre lo que espero, pero los otros son 0 no importa cuántos bucles existen.

Mostrador:

private static class Counter {
    private int count;

    public void increase() {
        count++;
    }

    public void decrease() {
        count--;
    }

    public int getCount() {
        return count;
    }
}

Persona:

// This is just a thread to increase and decrease the counter for many times.
private static class Person extends Thread {
    private Counter c;

    public Person(Counter c) {
        this.c = c;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100000; i++) {
            c.increase();
            c.decrease();
        }
    }
}

Método principal:

public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 10; i++) {
        Counter c = new Counter();
        Person p1 = new Person(c);
        Person p2 = new Person(c);
        p1.start();
        p2.start();
        p1.join();
        p2.join();
        System.out.println("run "+i+": "+c.getCount());        
   }
}

Salida:

run 0: 243
run 1: 12
run 2: 0
run 3: 0
run 4: 0
run 5: 0
run 6: 0
run 7: 0
run 8: 0
run 9: 0

No sé por qué el resto de los resultados son siempre 0. Pero supongo que se trata de la optimización de la JVM. ¿Es correcto que la JVM optimiza el código cuando se han hecho algunos bucles, y omite los bucles de descanso y siempre da 0 como respuesta?

SirFartALot:

Creo que la JVM es la optimización de aquí como usted ha dicho.

He añadido algunas salidas con períodos de tiempo a su pregunta, que muestran claramente, que la optimización sucede allí.

public static void main(String[] args) throws InterruptedException {

    for (int i = 0; i < 10; i++) {
        final long startTime = System.currentTimeMillis();
        Counter c = new Counter();
        Person p1 = new Person(c);
        Person p2 = new Person(c);
        p1.start();
        p2.start();
        p1.join();
        p2.join();
        final long endTime = System.currentTimeMillis();
        System.out.println(String.format("run %s: %s (%s ms)", i, c.getCount(), endTime - startTime));        
   }
}

resultados:

run 0: 1107 (8 ms)
run 1: 1 (1 ms)
run 2: 0 (2 ms)
run 3: 0 (0 ms)
run 4: 0 (0 ms)
run 5: 0 (0 ms)
run 6: 0 (1 ms)
run 7: 0 (0 ms)
run 8: 0 (0 ms)
run 9: 0 (0 ms)

Las primeras iteraciones del programa necesita una gran cantidad de tiempo, wheras en ejecución posterior casi no se utiliza ningún momento a todos.

Parece ser de fiar a Optimitzación sospechoso de este comportamiento.

El uso de un volatile int count:

run 0: 8680 (15 ms)
run 1: 6943 (12 ms)
run 2: 446 (7 ms)
run 3: -398 (7 ms)
run 4: 431 (8 ms)
run 5: -5489 (6 ms)
run 6: 237 (7 ms)
run 7: 122 (7 ms)
run 8: -87 (7 ms)
run 9: 112 (7 ms)

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=37596&siteId=1
Recomendado
Clasificación