单例模式

作者: n油炸小朋友 | 来源:发表于2018-05-20 20:58 被阅读20次

使用场景

频繁创建对象、管理对象是很耗费资源的事,有时候我们只需要一个对象就够了,这时候就需要用到单例模式。

单例模式的特点

  1. 单例模式只能有一个实例。

  2. 单例类必须创建自己的唯一实例。

  3. 单例类必须向其他对象提供这一实例。

单例模式与静态类

我们使用【静态类.doSomething();】和使用单例对象调用方法的效果是一样的,但是这是基于对象,单例模式是面对对象。

区别:

  1. 单例可以继承和被继承,方法可以被override,而静态方法不可以。

  2. 静态方法中产生的对象会在执行后被释放,进而被GC清理,不会一直存在于内存中。

  3. 静态类会在第一次运行时初始化,单例模式可以有其他的选择,即可以延迟加载。

  4. 基于2, 3条,由于单例对象往往存在于DAO层(例如sessionFactory),如果反复的初始化和释放,则会占用很多资源,而使用单例模式将其常驻于内存可以更加节约资源。

  5. 静态方法有更高的访问效率。

  6. 单例模式很容易被测试。

几个关于静态类的误解:

误解一:静态方法常驻内存而实例方法不是。

实际上,特殊编写的实例方法可以常驻内存,而静态方法需要不断初始化和释放。

误解二:静态方法在堆(heap)上,实例方法在栈(stack)上。

实际上,都是加载到特殊的不可写的代码内存区域中。

静态类和单例模式情景的选择:

情景一:不需要维持任何状态,仅仅用于全局访问,此时更适合使用静态类。

情景二:需要维持一些特定的状态,此时更适合使用单例模式。

代码实现单例模式

1 饿汉式

一开始就创建对象,如果该实例从始至终都没被使用过,则会造成内存浪费。

public class SingletonDemo {

    private static SingletonDemo instance=new SingletonDemo();

    private SingletonDemo(){ }

    public static SingletonDemo getInstance(){
        return instance;
    }

}

2 静态内部类

静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载,达到了类似懒汉模式的效果,而这种方法又是线程安全的。

public class SingletonDemo {

    private static class SingletonHolder{
        private static SingletonDemo instance=new SingletonDemo();
    }

    private SingletonDemo(){
        System.out.println("Singleton has loaded");
    }

    public static SingletonDemo getInstance(){
        return SingletonHolder.instance;
    }

}

3 枚举方法

这种写法真是太优雅了!!!!

解决了以下三个问题:

(1)自由序列化。

(2)保证只有一个实例。

(3)线程安全。

enum SingletonDemo{
    INSTANCE;

    public void otherMethods(){
        System.out.println("Something");
    }

}

使用时:

public class test {
    public static void main(String[] args){
        SingletonDemo.INSTANCE.otherMethods();
    }
}
4 懒汉式

设计成用到的时候再创建对象,但是在多线程下运行就不可靠了

public class SingletonDemo {

    private static SingletonDemo instance=null;

    private SingletonDemo(){}

    public static SingletonDemo getInstance(){

        if(instance==null){
            instance=new SingletonDemo();
        }
        return instance;

    }

}
5 线程安全的懒汉式

方法加上snychronized关键字,实现线程安全

public class SingletonDemo {
    private static SingletonDemo instance;

    private SingletonDemo(){ }

    public static synchronized SingletonDemo getInstance(){
        if(instance==null){
            instance=new SingletonDemo();
        }
        return instance;
    }

}
6 双重校验锁法

volatile 的功能:

  1. 避免编译器将变量缓存在寄存器里
  2. 避免编译器调整代码执行的顺序(也就是解决重排序的问题)
public class SingletonDemo {
    private volatile static SingletonDemo instance;
    private SingletonDemo(){
        System.out.println("Singleton has loaded");
    }
    public static SingletonDemo getInstance(){
        if(instance==null){//这次判断实际上是为了提高性能
            synchronized (SingletonDemo.class){
                if(instance==null){
                    instance=new SingletonDemo();
                }
            }
        }
        return instance;
    }
}
防止被反射攻击的单例模式
public class ElvisModified  
{  
    private static boolean flag = false;  
  
    private ElvisModified(){  
        synchronized(ElvisModified.class)  
        {  
            if(flag == false)  
            {  
                flag = !flag;  
            }  
            else  
            {  
                throw new RuntimeException("单例模式被侵犯!");  
            }  
        }  
    }  
  
    private  static class SingletonHolder{  
        private static final ElvisModified INSTANCE = new ElvisModified();  
    }  
  
    public static ElvisModified getInstance()  
    {  
        return SingletonHolder.INSTANCE;  
    }  
  
    public void doSomethingElse()  
    {  
  
    }  
}  

除此之外,单元素的枚举类型也可以防止被反射攻击。

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

    本文标题:单例模式

    本文链接:https://www.haomeiwen.com/subject/yogtjftx.html