单例模式

1. 什么是单例模式

  • 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

2. 使用单例模式的目的

  • 单例模式的目的是保证一个类有仅有一个实例,当实例创建以后不能在创建第二个该类的实例,从而节约系统资源

3. 单例模式实现步骤

  • 构造方法私有化,禁止对外提供构造方法,外部不能通过new 关键字来创建改类的实例。
  • 私有的静态成员置空(null)用于保存该类的实例。
  • 对外提供静态方法返回该类的唯一实例。

4. 单例模式实现例子

public 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;
    }

    //添加服务器
    public void addServer(String server) {
        serverList.add(server);
    }

    //删除服务器
    public void removeServer(String server) {
        serverList.remove(server);
    }

    public String getServer() {
        Random random = new Random();
        int i = random.nextInt(serverList.size());
        return (String) serverList.get(i);
    }


}

public class Client {
    public static void main(String args[]) {
        //创建 LoadBalancer 对象
        LoadBalancer balancer1, balancer2, balancer3, balancer4;
        balancer1 = LoadBalancer.getLoadBalancer();
        balancer2 = LoadBalancer.getLoadBalancer();
        balancer3 = LoadBalancer.getLoadBalancer();
        balancer4 = LoadBalancer.getLoadBalancer();

        if (balancer1 == balancer2 && balancer2 == balancer3 && balancer3 == balancer4) {
            System.out.println("服务器负载均衡具有唯一性!");
        }
        balancer1.addServer("Server1");
        balancer1.addServer("Server2");
        balancer1.addServer("Server3");
        balancer1.addServer("Server4");

        for (int i = 0; i < 10; i++) {
            String server = balancer1.getServer();
            System.out.println("分发请求到服务器: " + server);
        }

    }
}

基于枚举的实现方式

public enum LoadBalancer {

    BALANCER();

    //服务器集合
    private List serverList = null;

    //无参构造
    LoadBalancer() {
        this.serverList = new ArrayList();
    }

    //添加服务器
    public void addServer(String server) {
        serverList.add(server);
    }

    //删除服务器
    public void removeServer(String server) {
        serverList.remove(server);
    }

    //获取服务器
    public String getServer() {
        Random random = new Random();
        int i = random.nextInt(serverList.size());
        return (String) serverList.get(i);
    }
}

public class Client {
    public static void main(String args[]) {

        //创建 LoadBalancer 对象
        LoadBalancer balancer1, balancer2, balancer3, balancer4;
        balancer1 = LoadBalancer.BALANCER;
        balancer2 = LoadBalancer.BALANCER;
        balancer3 = LoadBalancer.BALANCER;
        balancer4 = LoadBalancer.BALANCER;

        //如果四个balancer是相同实例则执行
        if (balancer1 == balancer2 && balancer2 == balancer3 && balancer3 == balancer4) {
            System.out.println("服务器负载均衡具有唯一性!");
        }

        balancer1.addServer("Server1");
        balancer1.addServer("Server2");
        balancer1.addServer("Server3");
        balancer1.addServer("Server4");

        for (int i = 0; i < 10; i++) {
            String server = balancer1.getServer();
            System.out.println("分发请求到服务器: " + server);
        }
    }

}

5. 饿汉式单例

  • 饿汉式单例指的是在单例模式的基础上,将该类的唯一实例创建时期提前到类加载的时候创建,在外部调用的时候不需要做空判断。
public class LoadBalancer
{
    private static LoadBalancer instance = new LoadBalancer();

    private LoadBalancer(){}

    public static LoadBalancer getInstance()
    {
        return instance;
    }
}

6. 懒汉式单例

  • 懒汉式单例则与饿汉式单例相反,在类加载的时候并不会初始化创建该类的实例。而是在外部需要的时候(即调用getLoadBalancer方法)的时候才创建唯一实例。但是由此会产生多个线程同时调用无法保证全局唯一实例的问题。因此需要对单例类的实例方法进行加锁。
private volatile static LoadBalancer instance = null;
public static LoadBalancer getInstance()
{
	if(instance == null)
	{
		synchronized (LoadBalancer.class)
		{
			if(instance == null)
			{
				instance = new LoadBalancer();
			}
		}
	}
	return instance;
}
posted @ 2022-09-27 19:43  加瓦同学  阅读(20)  评论(0编辑  收藏  举报