【创建型模式】单例模式

一、单例模式概述

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

  • 要点
    • 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);
        }
	}
}

三、代码结构

相关推荐
亓才孓7 小时前
[JDBC]事务
java·开发语言·数据库
CHU7290357 小时前
直播商城APP前端功能全景解析:打造沉浸式互动购物新体验
java·前端·小程序
侠客行031713 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪13 小时前
深入浅出LangChain4J
java·langchain·llm
老毛肚15 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎15 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Yvonne爱编码16 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚16 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂16 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
fuquxiaoguang16 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析