大话设计模式-第21章 有些类也需计划生育--单例模式- 高飞网

第21章 有些类也需计划生育--单例模式

2016-02-02 13:21:43.0

单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。  

    通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且可以提供一个访问该实例的方法。  


public class Singleton{
        public static Singleton singleton;
        private Singleton(){}//构造方法私有化
        public static Singleton getInstance(){//提供外部创建实例的唯一入口
                if(singleton==null){//实例不存在是才创建
                        singleton = new Singleton();
                }
                return singleton;
        }
}
public class App{
        public static void main(String[] args){
                Singleton s1 = Singleton.getInstance();
                Singleton s2 = Singleton.getInstance();
                System.out.println(s1==s2);
        }
}

静态方法与单例的区别:

实用类不保存状态,仅提供静态方法或属性
单例类可以有状态
实用类不能用于继承多态
单例可以子类来继承
实用类只是一些方法属性的组合
单例类存在唯一对象

多线程环境中的单例

实例1:

public class Singleton{
    public static Singleton singleton;
    private Singleton(){}//构造方法私有化
    private final static Object syncObj = new Object();//程序运行时创建一个进程辅助对象
    public static Singleton getInstance(){//提供外部创建实例的唯一入口
        synchronized(syncObj){
            if(singleton==null){//实例不存在是才创建
                singleton = new Singleton();
            }  
        }  
        return singleton;
    }
}

但上面的方法每次进入getInstance()方法都会加锁,显示会影响效率,改进如下: 

//双重锁定
public class Singleton{
    public static Singleton singleton;
    private Singleton(){}//构造方法私有化
    private final static Object syncObj = new Object();//程序运行时创建一个进程辅助对象
    public static Singleton getInstance(){//提供外部创建实例的唯一入口
        if(singleton==null){//先判断实例是否为空再决定加锁处理
            synchronized(syncObj){
                if(singleton==null){//实例不存在是才创建
                    singleton = new Singleton();
                }  
            }  
        }  
        return singleton;
    }  

}

 

不涉及线程安全问题的单例 


//饿汉式
public class Singleton{
    public static Singleton singleton = new Singleton();
    private Singleton(){}//构造方法私有化
    public static Singleton getInstance(){//提供外部创建实例的唯一入口
        return singleton;
    }  

}