Existe alguma otimização para segurança do thread no loop de Java?

Kidsunbo:

Eu tenho um trecho de código que mudar um contador em dois tópicos. Não é o segmento de seguros, porque eu não colocar qualquer variável atômica ou bloqueio no código. Ele dá o resultado certo como eu esperava se o código executado apenas uma vez, mas eu quero executá-lo por várias vezes, então eu coloquei o código em um loop. E a questão é que apenas o primeiro ou os dois primeiros ciclos irá gerar o resultado que eu esperava. Para o resto dos loops, os resultados são sempre 0, o que parece ser thread-safe. Existe alguma operador interno em Java Virtual Machine resultando tal coisa?

Eu tentei alterar o número de loops, eo primeiro um ou dois são sempre o que eu esperava, mas os outros são 0, não importa quantas voltas existem.

Contador:

private static class Counter {
    private int count;

    public void increase() {
        count++;
    }

    public void decrease() {
        count--;
    }

    public int getCount() {
        return count;
    }
}

Pessoa:

// 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());        
   }
}

Resultado:

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

Eu não sei por que o resto dos resultados são sempre 0. Mas eu acho que é sobre a otimização da JVM. É certo que a JVM otimiza o código quando alguns loops ter sido feito, e omite os loops de descanso e sempre dá 0 como resposta?

SirFartALot:

Eu acho que a JVM é otimizar aqui como você disse.

Eu adicionei algumas saídas com horários à sua pergunta, que mostram claramente, que a otimização acontece lá.

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)

As primeiras iterações o programa precisa de muito tempo, wheras em execução posterior quase nenhum momento a todos é usado.

Parece ser legítimo para optimazation suspeito para esse comportamento.

Usando um 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)

Acho que você gosta

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