【创建型模式】单例模式

一、单例模式概述

单例模式的定义又叫单件模式,确保一个类只有一个实例,并提供一个全局访问点(对象创建型)

  • 要点
    • 1.某个类只能有一个实例;
    • 2.必须自行创建这个实例;
    • 3.必须自行向整个系统提供这个实例。
  • 单例模式的优缺点
    • 优点:
      • 1.提供了对唯一实例的受控访问
      • 2.可以节约系统资源,提高系统的性能
      • 3.允许可变数目的实例(多例类)
    • 缺点:
        1. 全局变量:单例模式实质上就是全局变量。全局变量可能会被误修改,而且调试困难;
        1. 并发问题:在多线程环境下,如果没有正确地处理,可能会导致多个实例被创建;
      • 3.单例类通常承担了太多的职责,因为为了让某个类的对象共享,就把这个类设计成了单例类,这违反了单一职责原则.
  • 适用环境
    • 1.系统只需要一个实例对象,或者因为资源消耗太大而只允许创建一个对象
    • 2.客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例
  • 饿汉式单例类与懒汉式单例类的比较
    • 饿汉式
      • 1.无需考虑多个线程同时访问的问题;
      • 2.调用速度和反应时间优于懒汉式单例;
      • 3.资源利用率不及懒汉式单例;
      • 4.系统加载时间可能会比较长。
    • 懒汉式
      • 1.实现了延迟加载;
      • 2.必须处理好多个线程同时访问的问题;
      • 3.需要通过双重检查锁定等机制进行控制,将导致系统性能受到一定的影响。

二、代码实现

单例模式只有一个角色:单例角色

2.1 单例角色(LoadBalancer)
java 复制代码
//designpatterns.singleton.LoadBalancer.java
package singleton;
import java.util.*;

//负载均衡器类,充当单例角色
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);
	}
		
	//使用Random类随机获取服务器
	public String getServer() {
		Random random = new Random();
		int i = random.nextInt(serverList.size());
		return (String)serverList.get(i);
	}
}
2.2 main方法实现单例模式(Client)
java 复制代码
//designpatterns.singleton.Client.java
package singleton;

//客户端测试类
public class Client {
	public static void main(String args[]) {
		//创建4个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("Server 1");
		balancer1.addServer("Server 2");
		balancer1.addServer("Server 3");
		balancer1.addServer("Server 4");
		
		//模拟客户端请求的分发,如果输出结果全为同一个server,可以将i适当放大,
		//例如改为"i < 100"
		for (int i = 0; i < 10; i++) {
            String server = balancer1.getServer();
            System.out.println("分发请求至服务器: " + server);
        }
	}
}

三、代码结构

相关推荐
救救孩子把12 分钟前
深入理解 Java 对象的内存布局
java
落落落sss14 分钟前
MybatisPlus
android·java·开发语言·spring·tomcat·rabbitmq·mybatis
万物皆字节20 分钟前
maven指定模块快速打包idea插件Quick Maven Package
java
夜雨翦春韭27 分钟前
【代码随想录Day30】贪心算法Part04
java·数据结构·算法·leetcode·贪心算法
我行我素,向往自由33 分钟前
速成java记录(上)
java·速成
一直学习永不止步39 分钟前
LeetCode题练习与总结:H 指数--274
java·数据结构·算法·leetcode·数组·排序·计数排序
邵泽明39 分钟前
面试知识储备-多线程
java·面试·职场和发展
程序员是干活的1 小时前
私家车开车回家过节会发生什么事情
java·开发语言·软件构建·1024程序员节
煸橙干儿~~1 小时前
分析JS Crash(进程崩溃)
java·前端·javascript
2401_854391081 小时前
Spring Boot大学生就业招聘系统的开发与部署
java·spring boot·后端