单例模式

单例模式是指一个类只能有一个实例。单例模式可以避免实例的重复创建,全局访问的都是一个实例。创建单例模式大致思路就是将构造方法定义为私有,其他类不能实例化新的对象。创建单例模式有5种方式:

懒汉模式:

懒汉模式是常用的写法:

优点:

1、延迟加载。

缺点:

1、 在多线程情况下会存在问题,需要加同步关键字解决。但是同步后,性能会严重损耗。

2、可以通过反射重复建立实例。

 class LazySingleton{
    private static LazySingleton singleton=null;
    private LazySingleton(){
    }
    public synchronized static LazySingleton getInstance(){
        if(singleton==null){
            singleton=new LazySingleton();
        }
        return singleton;
}   
public String getName(){  
        return "fxt";  
    }
}

调用时:

String name =LazySingleton.getInstance().getName();

   System.out.println(name);

反射破解步骤:

//获取构造方法

            Constructorconstructor = Class.forName("singletonTest.single1").getDeclaredConstructor();

            //可获取私有方法

            constructor.setAccessible(true);

            //获得实例

            System.out.println(constructor.newInstance());

       System.out.println(constructor.newInstance());

得到的两个实例是不一样的。

饿汉模式:

优点:

1、由于加载类时就创建实例,所以线程安全(多个类加载器除外)。

缺点:

1、 没有达到延迟加载(懒加载)的效果。

2、可通过反射创建多个实例

 class HungrySingleton{
    private static HungrySingleton singleton=new HungrySingleton();
    private HungrySingleton(){}
    public static HungrySingleton getInstance(){
        return singleton;
    }
}

静态内部类:

优点:

加载时,不会初始化静态变量 INSTANCE,达到懒加载效果。

class InternalSingleton{
    private static class SingletonHolder{
        private final static  InternalSingleton INSTANCE=new InternalSingleton();
    }   
    private InternalSingleton(){}
    public static InternalSingleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}


枚举:


优点:

1、可以防止通过反射,多次创建对象。

2、线程安全

缺点:

1、失去类的一些特性

2、没有延迟加载


 enum EnumSingleton{
    INSTANCE;
    		public String getName(){  
        	return "name";  
    }
}

调用时:

String name=EnumSingleton.INSTANCE.getName();

       System. out.println(name);

双重校验锁:

 class LockSingleton{
    private volatile static LockSingleton singleton;
    private LockSingleton(){}
    public static LockSingleton getInstance(){
        if(singleton==null){
            synchronized(LockSingleton.class){
                if(singleton==null){
                    singleton=new LockSingleton();
                }
            }
        }
        return singleton;
    }}


说明:

这种方法在JDK1.5之前是行不通的(1.5之后可以使用 volatile,这个关键字可以禁止重排序),因为JVM的重排序, singleton= new LockSingleton();代码在执行时,不一定按照a.初始化对象àb.实例化对象(调用构造方法)àc.将对象引用返回给 singleton,这个顺序,c有可能在b之前就运行,因此返回一个只初始化但是没有实例化的对象(不知理解的准确否???其他地方的实例化都有这种可能吗???),其他线程在判断singleton是否为null时,已经不为null了, 但是只是初始化没有实例化,这是就会出现问题。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值