单例模式
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;
}