1. Singleton estilo chinês faminto
Copie o código do código da seguinte forma:
classe pública Singleton {
private final static Singleton INSTANCE = new Singleton();
Singleton privado() { }
public static Singleton getInstance() {
retornar INSTÂNCIA;
}
}
2. Com ajuda de aulas internas
É um singleton preguiçoso porque o mecanismo Java estipula que a classe interna SingletonHolder só será carregada (implementada preguiçosamente) quando o método getInstance() for chamado pela primeira vez e seu processo de carregamento for thread-safe. A instância é instanciada uma vez quando a classe interna é carregada.
Copie o código do código da seguinte forma:
classe pública Singleton {
Singleton privado() { }
classe estática privada SingletonHolder {
private final static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
retornar SingletonHolder.INSTANCE;
}
}
3. Solução de bloqueio comum
Copie o código do código da seguinte forma:
classe pública Singleton {
instância Singleton estática privada = null;
Singleton privado() { }
público estático sincronizado Singleton getInstance() {
if(instância == nulo) {
instância = novo Singleton();
}
instância de retorno;
}
}
Embora o problema de segurança do thread seja resolvido, cada thread que chama getInstance deve ser bloqueado. Queremos bloquear apenas na primeira vez que getInstance é chamado.
4. Detecção dupla, mas preste atenção ao método de escrita
Copie o código do código da seguinte forma:
classe pública Singleton {
instância Singleton estática privada = null;
Singleton privado() { }
public static Singleton getInstance() {
if(instância == nulo) {
sincronizado(Singleton.class) {
Temperatura Singleton = instância;
if(temp == nulo) {
temp = novo Singleton();
instância=temp
}
}
}
instância de retorno;
}
}
Devido ao problema de reordenação da instrução, ela não pode ser escrita diretamente da seguinte forma:
classe pública Singleton {
instância Singleton estática privada = null;
Singleton privado() { }
public static Singleton getInstance() {
if(instância == nulo) {
sincronizado(Singleton.class) {
if(instância == nulo) {
instância = novo Singleton();
}
}
}
instância de retorno;
}
}
Mas se a variável de instância for modificada com volátil, tudo bem. Se for modificado com volátil, pode garantir que as instruções correspondentes de instance = new Singleton(); seguro:
classe pública Singleton {
instância privada estática volátil Singleton = null;
Singleton privado() { }
public static Singleton getInstance() {
if(instância == nulo) {
sincronizado(Singleton.class) {
if(instância == nulo) {
instância = novo Singleton();
}
}
}
instância de retorno;
}
}