boa noite a todos! estou estudando Singleton e me deparei com o seguinte código:
public class Singleton1 {
private volatile static Singleton1 uniqueStance;
private Singleton1() {}
public static Singleton1 getInstance()
{
if(uniqueStance == null)
{
synchronized(Singleton1.class)
{
if(uniqueStance == null)
{
uniqueStance = new Singleton1();
}
}
}
// por que são usados dois if's ?
// o primeiro já não verifica se a instância única é null ?
return uniqueStance;
}
}
Eu não entendi o porquê de ser necessário fazer essa dupla checagem e gostaria de saber se essa definição de volatile está correta:
“Volatile: In a multithreaded program sometimes two or more threads share
same variable. For efficiency each thread keeps its own private copy of the
shared variable and work on it. If you want to restrict the thread from
using your own private copy of the variable and let them use master copy of the
shared variable then modify variable using volatile modifier. In
short we can say that volatile modifier can not be cached by the threads.”
A dupla checagem é um mito. Foi provado que ela só funcionaria em Java se ele seguisse um determinado “memory model”, que não é obrigatoriamente seguido por todas as implementações.
Leia o artigo abaixo:
Eu ainda estou lendo o primeiro artigo mas devo dizer que estou pasmo. :shock: Não sabia que os threads não deveriam ser subestimados :lol: fazer uma variável passar a ser not null antes mesmo do construtor ser executado ?! :shock:
Isso, simples assim. Na verdade, como a inicialização é garantida pela VM, e o valor da variável instance é constante, você poderia até tirar o volatile.
Agora, depois do Java 5, o melhor é usar um enum:
public enum Singleton {
INSTANCE;
private int x;
public int getX() { return x; }
public void setX() { this.x = x; }
}
Outra pergunta: aquele artigo da IBM é de 2002, nos dias atuais ainda ocorre o problema nos compiladores JIT de que uma variável pode se tornar “non-null” antes mesmo do construtor ser executado ? isso pode acontecer em outras linguagens que não usam compiladores JIT ?