单例模式:用来创建唯一的实例对象

想要保证对象唯一:

1.为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象

2.还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。

3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

这三部怎么用代码体现呢?

1.将构造函数私有化。

2.在类中创建一个本类对象。

3.提供一个方法可以获取到该对象。

 

实现方式一:只适合单线程环境(不好)

public class Singleton {
    private static Singleton singleton=null;
    private Singleton(){
        
    }
    public static Singleton getInstance(){
        if(singleton==null){
            singleton=new Singleton();
        }
        return singleton;
    }
}

缺点:只在单线程的情况下正常运行,在多线程情况下就会出问题。
例如:当两个线程同时运行到判断instance是否为空的if语句,并且instance确实没有创建好时,那么两个线程都会创建一个实例

 

实现方式二:多线程的情况能用。(懒汉式,不好)

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

在方式一的基础上加了同步锁,使得在多线程的情况下可以用,保证了在多线程的环境下也只有一个实例

 

实现方式三:加同步锁时,前后两次判断实例是否存在(可行)

public class Singleton {
    private static Singleton singleton=null;
    private Singleton(){
        
    }
    public static Singleton getInstance(){
        if(singleton==null){
synchrized(Stringleton.class){
if(singleton==null){
    singleton=new Singleton();
}  
} } return singleton; } }

只有当singleton为null时,需要获取同步锁,创建一次实例。当实例被创建,则无需视图加锁

 

实现方式四:饿汉式(建议使用)

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

缺点:降低内存的使用率

 

实现方式五:静态内部内(建议使用)

public class Singleton {
    private Singleton(){
        
    }
    private static class SingletonHolder{
        private final static Singleton singleton=new Singleton();    
    }
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

不论是静态内部类还是非静态内部类,都是在第一次使用时才会被加载

 

posted on 2018-03-09 10:41  sonofthesea  阅读(247)  评论(0编辑  收藏  举报