【创建型模式】单例模式

一、单例模式概述

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

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

三、代码结构

相关推荐
雷神乐乐5 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。8 分钟前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野15 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航18 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself33 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041538 分钟前
J2EE平台
java·java-ee
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
豪宇刘1 小时前
SpringBoot+Shiro权限管理
java·spring boot·spring
Elaine2023911 小时前
02多线程基础知识
java·多线程
gorgor在码农1 小时前
Redis 热key总结
java·redis·热key