O padrão singleton é um dos 23 padrões de design. É um padrão de design relativamente simples. Seu objetivo é retornar o mesmo objeto, não importa quantas vezes seja chamado.
Ele é dividido em duas estruturas, uma é o estilo do homem preguiçoso e a outra é o estilo do homem faminto. Cada uma delas tem suas próprias vantagens e desvantagens.
public class Single { private static Single = new Single(); private Single() { } public Single getInstance() { return single;
Pode-se ver no programa acima que, embora nosso propósito de carregar o mesmo objeto tenha sido realmente alcançado, o único objeto será criado quando o programa for carregado. Quando esta classe tiver vários desses métodos, não podemos usá-los. neste objeto causará um desperdício de memória. Então surgiu o padrão singleton preguiçoso. O código é o seguinte:
classe pública Single { private static Single = null; private Single() { } public Single getInstance() { if(single==null){ single = new Single();
Dessa forma, o objeto só será novo quando realmente o chamarmos, mas há um problema nisso.
Quando o segundo trecho de código acima é chamado por dois threads quando é carregado pela primeira vez, dois objetos diferentes serão gerados, portanto, o thread não é seguro. Neste momento, você pensará em adicionar um Lock, o código após o bloqueio. é o seguinte:
classe pública Único { privado estático Único único = nulo; privado Único() { } público sincronizado Único getInstance() { if (único == nulo) { único = novo Único();
Isso garante a segurança do thread, mas quando o método de bloqueio precisa realizar muitas coisas, chamar esse método levará muito tempo, o que é fatal para o servidor, porque se um thread continuar chamando esse método, não há como ajustar outros threads e o servidor serão bloqueados. O código atualizado será o seguinte:
public class Single { priate static Single = null; private Single() { } public Single getInstance() { if (single == null) { sincronizado (Single.class) { single = new Single(); } }
Após observação cuidadosa, descobri que não há bloqueio dessa forma. Quando dois threads chegam ao método getInstance() se forem julgados pela primeira vez, um deles deve ser bloqueado. não mais Para determinar se está vazio, um objeto ainda será criado. Desta forma, vários objetos serão gerados e, em seguida, atualizados.
classe pública Single { private static Single = null; private Single() { } public Single getInstance() { if (single == null) { sincronizado (Single.class) { if (single == null) { single = new Single (); } } } retornar único;
Desta forma, o problema acima não ocorrerá e será bloqueado apenas uma vez, pois quando o método for executado pela segunda vez, o julgamento if será ignorado e o single será retornado diretamente. , e a eficiência de execução será muito alta.
Mas mesmo assim, ainda há um problema, porque não podemos ter certeza se o objeto recebe um valor na memória primeiro ou se o objeto é criado primeiro, então o segundo programa pode obter um objeto meio inicializado em jdk1. , podemos usar a palavra-chave volátil para evitar esta situação. O código é o seguinte:
classe pública Único { privado estático volátil Único único = nulo; privado Único () { } público Único getInstance () { if (único == nulo) { sincronizado (Single.class) { if (único == nulo) { único = novo Único(); } } } retornar único;
Mas essa situação raramente é usada, só estou aqui para aprender, hehe.