定义:单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
单例模式根据实例化对象的情况分为两种:
- 饿汉模式:例在单例类被加载时候,就实例化一个对象交给自己的引用;
- 懒汉模式:在调用取得实例方法的时候才会实例化对象。
一、特点
- 单例类只能有一个实例。
- 单例类必须自己自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
二、单例模式的要点
- 私有的构造方法
- 指向自己实例的私有静态引用
- 以自己实例为返回值的静态的公有的方法
三、优点
- 在内存中只有一个对象,节省内存空间。
- 避免频繁的创建销毁对象,可以提高性能。
- 避免对共享资源的多重占用。
- 可以全局访问。
四、缺点
- 扩展困难,由于getInstance静态函数没有办法生成子类的实例。如果要拓展,只有重写那个类。
- 隐式使用引起类结构不清晰。
- 导致程序内存泄露的问题。
五、适用场景
- 需要频繁实例化然后销毁的对象。
- 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
- 资源共享的情况下,避免由于资源操作时导致的性能或损耗等
- 控制资源的情况下,方便资源之间的互相通信。
六、单例模式注意事项:
- 只能使用单例类提供的方法得到单例对象,不要使用反射,否则将会实例化一个新对象。
- 不要做断开单例类对象与类中静态引用的危险操作。
- 多线程使用单例使用共享资源时,注意线程安全问题。
/**
* @program: Design
* @description: 单例模式
* @author: lijun
* @create: 2020-05-22 09:19
**/
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
/**
* @Author lijun
* @Description 饿汉模式
* @Date 9:20 2020/5/22
* @Param []
* @return com.lijun.design.singleton.Singleton
**/
public static Singleton getInstance(){
return singleton;
}
}
/**
* @program: Design
* @description: 单例模式
* @author: lijun
* @create: 2020-05-22 09:43
**/
public class Singleton2 {
private static Singleton2 singleton = new Singleton2();
private Singleton2(){}
/**
* @Author lijun
* @Description 懒汉模式
* @Date 9:20 2020/5/22
* @Param []
* @return com.lijun.design.singleton.Singleton
**/
public static synchronized Singleton2 getInstance(){
if(singleton==null){
singleton = new Singleton2();
}
return singleton;
}
}
单例模式还有一种比较常见的形式:双重锁的形式
这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。这种模式中双重判断加同步的方式,比第一个例子中的效率大大提升,因为如果单层if判断,在服务器允许的情况下,假设有一百个线程,耗费的时间为100*(同步判断时间+if判断时间),而如果双重if判断,100的线程可以同时if判断,理论消耗的时间只有一个if判断的时间。所以如果面对高并发的情况,而且采用的是懒汉模式,最好的选择就是双重判断加同步的方式
/**
* @program: Design
* @description: 双重锁模式
* @author: lijun
* @create: 2020-05-22 09:21
**/
public class Singleton1 {
private static volatile Singleton1 instance=null;
private Singleton1(){
//do something
}
/**
* @Author lijun
* @Description
* @Date 9:31 2020/5/22
* @Param []
* @return com.lijun.design.singleton.Singleton1
**/
public static Singleton1 getInstance(){
if(instance==null){
synchronized(Singleton1.class){
if(instance==null){
instance=new Singleton1();
}
}
}
return instance;
}
}
网友评论