一、什么是单例模式  

单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
其实,GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。 
 
二、为什么要使用单例模式呢?
在应用系统开发中,我们常常有以下需求:
- 在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象
- 在整个程序空间使用全局变量,共享资源
- 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。
因为Singleton模式可以保证为一个类只生成唯一的实例
对象,所以这些情况,Singleton模式就派上用场了。
 
三、单例模式实现
1.饿汉式:
[java] 
package com.qianyan.singleton;  
public class Person {  
    private static final Person person = new Person();  
    private String name;  
    //构造方法私有化  
    private Person(){  
    }  
    //创建一个全局可访问的静态方法  
    public static Person getInstance(){  
        return person;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
}  
2.懒汉式(非线程安全,在多线程下有问题):
[java]  
package com.qianyan.singleton;  
public class Person1 {  
    private static Person1 person;  
    private String name;  
    //私有化构造方法  
    private Person1(){  
    }  
    //创建一个全局可访问的静态方法  
    public static Person1 getInstance(){  
        if(person == null)  
            return new Person1();  
        return person;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
}  
线程安全(效率低):
[java] 
package com.qianyan.singleton;  
public class Person2 {  
    private static Person2 person;  
    private String name;  
    //私有化构造方法  
    private Person2(){  
    }  
    //创建一个全局可访问的静态方法,使用同步方法  
    public static synchronized Person2 getInstance(){  
        if(person == null)  
            person = new Person2();  
        return person;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
}  
3.双重检查:
[java]  
package com.qianyan.singleton;  
public class Person3 {  
    private static Person3 person;  
    private String name;  
    //私有化构造方法  
    private Person3(){  
    }  
    //创建一个全局可访问的静态方法,使用同步方法  
    public static Person3 getInstance(){  
        if(person == null)  
            synchronized(Person3.class){  
                if(person == null)  
                    person = new Person3();  
            }  
        return person;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
}  
测试类:
[java]  
package com.qianyan.singleton;  
public class MainClass {  
    public static void main(String[] args) {  
        /*Person p1 = Person.getInstance(); 
        p1.setName("zhangsan"); 
        Person p2 = Person.getInstance(); 
        p2.setName("lisi"); 
        System.out.println(p1.getName()); 
        System.out.println(p2.getName());*/  
        /*Person1 p1 = Person1.getInstance(); 
        p1.setName("zhangsan"); 
        Person1 p2 = Person1.getInstance(); 
        p2.setName("lisi"); 
        System.out.println(p1.getName()); 
        System.out.println(p2.getName());*/  
        /*Person2 p1 = Person2.getInstance(); 
        Person2 p2 = Person2.getInstance(); 
        p1.setName("zhangsan"); 
        p2.setName("lisi"); 
        System.out.println(p1); 
        System.out.println(p2);*/  
        Person3 p1 = Person3.getInstance();  
        Person3 p2 = Person3.getInstance();  
        p1.setName("zhangsan");  
        p2.setName("lisi");  
        System.out.println(p1.getName());  
        System.out.println(p2.getName());  
    }  
}