Custo do uso dos campos finais
Sabemos que tornar os campos finais geralmente é uma boa ideia, à medida que obtemos segurança e imutabilidade do encadeamento, o que facilita o raciocínio do código. Estou curioso para saber se há um custo de desempenho associado.
O Java Memory Model garante issofinal Field Semantics
:
Um encadeamento que só pode ver uma referência a um objeto depois que o objeto foi completamente inicializado tem a garantia de ver os valores inicializados corretamente para os campos finais desse objeto.
Isso significa que para uma classe como esta
class X {
X(int a) {
this.a = a;
}
final int a;
static X instance;
}
sempre que o Thread 1 cria uma instância como esta
X.instance = new X(43);
while (true) doSomethingEventuallyEvictingCache();
e o Thread 2 vê
while (X.instance == null) {
doSomethingEventuallyEvictingCache();
}
System.out.println(X.instance.a);
deve imprimir 43. Sem ofinal
modificador, o JIT ou a CPU poderia reordenar as lojas (primeira lojaX.instance
e depois definaa=43
) e o Thread 2 pode ver o valor inicializado por padrão e imprimir 0.
Quando o JIT vêfinal
obviamente evita reordenar. Mas também precisa forçar a CPU a obedecer à ordem. Existe uma penalidade de desempenho associada?