单例模式——NWU_LK

单例模式

基本概念

所谓的单例模式指的是,采取一定的方法,使得整个系统中一个类只有一个实例对象,该类只提供一个取得该实例的方法(静态方法)

单例模式适用场景

需要频繁进行创建和销毁的对象。创建对象时耗时过多浪费时间和资源。

实现方式

单例模式一共有七种:

  • 饿汉式(静态常量)
  • 饿汉式(静态代码块)
  • 饿汉式(枚举)
  • 懒汉式(线程不安全)
  • 懒汉式(线程安全,同步方法)
  • 懒汉式(线程安全,同步代码块,双重判断)
  • 懒汉式(静态内部类)
代码实现

1 .饿汉式(静态常量)
优点:类装载时就完成了实例化,不存在同步问题。
缺点:类装载时就完成了实例化,不使用的话就造成了内存的浪费

class singleTon{
    private singleTon(){}
    private final static singleTon instance=new singleTon();
    public static singleTon getInstance(){
        return instance;
    }
}
  1. 饿汉式(静态代码块)
    和静态常量基本相同,同样的缺点和优点。
class singleTon{
    private singleTon(){}
    private static singleTon instance;
    static {
        instance=new singleTon();
    }
    public static singleTon getInstance(){
        return instance;
    }
}
  1. 饿汉式(枚举)
    优点:避免反序列化重新创建对象,实现了同步,java作者推荐使用的方式。
    缺点:不能延时加载
enum single{
    INSTANCE;
}
  1. 懒汉式(线程不安全)
    优点:起到了懒加载的作用
    缺点:线程不安全,实际开发中不用
class singleTon{
    private singleTon(){}
    private static singleTon instance;
    public static singleTon getInstance(){
        if (instance==null){
            instance=new singleTon();
        }
        return instance;
    }
    public void test(){
        System.out.println("创建");
    }
}
  1. 懒汉式(线程安全,同步方法)
    优点:起到了懒加载和创建时线程不同步的问题
    缺点:效率低下,同一时间只能有一个线程得到对象,创建后各个线程应该可以随意得到对象
class singleTon{
    private singleTon(){}
    private static singleTon instance;
    public synchronized static singleTon getInstance(){
        if (instance==null){
            instance=new singleTon();
        }
        return instance;
    }
    public void test(){
        System.out.println("创建");
    }
}
  1. 懒汉式(线程安全,同步代码块,双重判断)
    volatile关键字保证可见性,防止指令重排
    指令重排:分配内存,创建对象,引用指向对象顺序可能会乱,比如先引用指向对象然后再创建完成对象
class single{
    private singleTon(){}
    private static volatile singleTon instance;
    public static singleTon getInstance(){
        if (instance==null){
            synchronized(singleTon.class){
                if (instance==null){
                    instance=new singleTon();
                }
            }
        }
        return instance;
    }
}
  1. 懒汉式(静态内部类)
    优点:因为外部类加载时内部类不会一起加载,所以起到了懒加载的作用。使用inner.instance时内部类才会装载
class single{
    private single(){}
    private static class inner{
        private static final single instance=new single();
    }
    public static single getInstance(){
        return inner.instance;
    }
}
问题

恶汉式、懒汉式的方式还不能防止反射来实现多个实例,通过反射的方式,设置ACcessible.setAccessible方法可以调用私有的构造器,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。

private static int i = 1; 
private Singleton() { 
   if(i==1){ 
     i++; 
   }else{ 
     throw new RuntimeException("只能调用一次构造函数"); 
   } 
} 

这样还不能保证单例,当序列化后,反序列化是还可以创建一个新的实例,在单例类中添加readResolve()方法进行防止。

private Object readResolve(){ 
    return instance; 
} 
JAVA中的使用

系统类Runtime用到了单例模式
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值