一、什么是单例模式
单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
其实,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());
}
}