单例模式概述
单例模式概述
单例模式一
定义:
确保某一个类,只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类成为单例类,它提供全局访问的方法。单例模式是一种创建对象的模式。
分析
某个类只能创建一个实例,由这一点我们可以知道,这个类不能在外部创建只能在类的内部创建。那么如何实现这一点呢!我们可以通过将这个类的构造函数,设置为私有变量。
既然我们已经将构造函数设置为私有的了,那么如何在内部创建类呢?并且要保证其唯一性?我们可以声明一个静态的私有的成员变量,并且声明一个公有的静态的函数对其便来给你进行判断,判断其是否唯一,并且是否已创建。
要点
某个类只能有一个实例。
他必须自动创建。
他必须自行像整个系统提供这个实例。
我们看一个简单的例子
package com.boke.danli;
public class Main {
public static void main(String args[]){
Singleton a,b;
a=Singleton.GetInstance();
b=Singleton.GetInstance();
if(a==b){
System.out.println("实例唯一");
}
}
}
package com.boke.danli;
import sun.security.jca.GetInstance;
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public static Singleton GetInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
单例模式二
在多线程的环境下,假设多个线程同时调用GetInstance()方法,且其都测得instance==null,那么系统中将产生多个对象,这样就违反了,单例模式的本意,因此我们提供两种方法:懒汉模式与饿汉模式
饿汉模式
什么是饿汉模式呢?饿汉模式就是在加载类的时候,产生一个实例,不用再以后判断实力是否存在而生成其实例对象。
package com.boke.danli;
public class Main {
public static void main(String args[]){
EagerSingleton a,b;
a=EagerSingleton.GetInstance();
b=EagerSingleton.GetInstance();
if(a==b){
System.out.println("实例唯一");
}
}
}
package com.boke.danli;
public class EagerSingleton {
private static final EagerSingleton instance=new EagerSingleton();
private EagerSingleton(){
}
public static EagerSingleton GetInstance(){
return instance;
}
}
懒汉模式
根据UML图我们可以知道,其创建跟单例模式一没有什么区别,但在创建时,我们运用一种加锁的机制!使其防止多进程访问而产生的,不唯一性
我们可以看具体代码
package com.boke.danli;
public class LazySingleton {
private static LazySingleton instance=null;
private LazySingleton(){
}
public static LazySingleton getInstance(){
if(instance==null){
synchronized (LazySingleton.class){
if(instance==null){
instance=new LazySingleton();
}
}
}
return instance;
}
}
懒汉模式和饿汉模式的优缺点
单例模式三
IoDH
package com.boke.danli;
public class IoDHSingleton {
private IoDHSingleton(){
}
private static class HolderClass{
private final static IoDHSingleton instance=new IoDHSingleton();
}
public static IoDHSingleton getInstance(){
return HolderClass.instance;
}
public static void main(String args[]){
IoDHSingleton a,b;
a=IoDHSingleton.getInstance();
b=IoDHSingleton.getInstance();
System.out.println(a==b);
}
}
单例模式的优缺点
优点:
1.实例唯一
2.节约资源
3.允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获
得指定个数的对象实例,既节省系统资源,又解决了单例单例对象共享过多有损性能的问
题。
缺点:
1.无抽象层
2.单例类的指责过重。
3.现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如
果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次
利用时又将重新实例化,这将导致共享的单例对象状态的丢失。
应用场景
(1) 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
(2) 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
欢迎进群交流