单例模式 饿汉与懒汉

单例模式

就像任务管理器一样,只能由一个实例,你不能同时打开两个任务管理器,所以单例模式的对象不可以再外部通过new来创建,只能再类里通过private static来保证她的单例属性,再声明一个public函数来访问她。

** 私有静态成员单例**+
私有单例构造函数+
公有访问函数

任务管理器例子

//由于每次使用new关键字来实例化TaskManager类时都将产生一个新对象, 为了确保
//TaskManager实例的唯一性, 我们需要禁止类的外部直接使用new来创建对象, 因此需要将
//TaskManager的构造函数的可见性改为private

//构造函数改为private修饰后该如何创建对象呢? 不要着急, 虽然类的外部无法再使用new
//来创建对象, 但是在TaskManager的内部还是可以创建的, 可见性只对类外有效。 因此, 我们
//可以在TaskManager中创建并保存这个唯一实例。 为了让外界可以访问这个唯一实例, 需要在
//TaskManager中定义一个静态的TaskManager类型的私有成员变量,

//为了保证成员变量的封装性, 我们将TaskManager类型的tm对象的可见性设置为private, 但
//外界该如何使用该成员变量并何时实例化该成员变量呢? 答案是增加一个公有的静态方法,

class TaskManager{
    private static TaskManager tm = null;
    private TaskManager(){}
    public static TaskManager getInstance(){
        if (tm==null){
            tm = new TaskManager();
        }
        return tm;
    }
    public void displayProcess(){}

}

负载均衡器

不管客户端代码。调用几次访问函数,她返回的都是唯一实例(地址相同)

import java.util.*;
class LoadBalancer {
    private static LoadBalancer instance = null;

    private List serverList = null;
    //私有构造函数
    private LoadBalancer(){
        serverList =new ArrayList();
    }
    //公有静态成员方法。返回唯一实例
    public static LoadBalancer getLoadBalancer(){
        if(instance==null){
            instance =new LoadBalancer();
        }
        return instance;
    }

    //add server
    public void addServer(String server){
        serverList.add(server);
    }

    //delete server
    public void removeServer(String server){
        serverList.remove(server);
    }

    //using Random class randomly gets server
    public String getServer(){
        Random random = new Random();
        int i = random.nextInt(serverList.size());
        return (String)serverList.get(i);
    }

}

存在的缺陷

如果把上列的单例模式放再生产线中,会出现一个问题:如果线程A首次访问,发现为null则去创建一个新的,再创建的过程中,线程B也访问,又创建了一个。这样就违背了单例原创,一个系统中则存在好几个单例,如何解决这个问题呢,有两个方案,饿汉和懒汉。

饿汉

在声明的时候就初始化,不给多线程而带来的初始化时间差机会。

public class EagerSingleton {
    private static final EagerSingleton instance =new EagerSingleton;
    private EagerSingleton(){}
    public static EagerSingleton getInstance(){
        return instance;
    }
}

懒汉

使用同步锁synchronized

package method.Singleton;

public class LazySingleton {
    
    private static LazySingleton instance = null;
    private LazySingleton(){}
    
    public static LazySingleton getInstance(){
        if(instance == null){
             synchronized(LazySingleton.calss){
                instance = new LazySingleton();
            }
        }
        return instance;
    }
}

个人小站:http://jun10ng.work/ 拥抱变化,时刻斗争,走出舒适圈。
原文地址:https://www.cnblogs.com/Jun10ng/p/12372145.html