1.定义
单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
GOF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局方法。
2.为什么要使用单例模式?
在开发中,经常有如下需求:
- 在多个线程之间,比如servlet环境,共享一个资源或者操作同一个对象。
- 在整个程序空间使用全局变量,共享资源。
- 大规模系统中,为了性能考虑,需要节省对象的创建时间等。
3.单例模式实现
- 饿汉式
- 懒汉式
- 双重检查
4.代码演示
/** * 饿汉式 (是线程安全的) * */ public class Person { private String name; //静态常量 private static final Person per = new Person(); //构造函数私有化 private Person() { } public String getName() { return name; } public void setName(String name) { this.name = name; } //提供一个全局的静态方法 public static Person getPersonInstance() { return per; } }
package test.com.singleton; /** * 懒汉式 (线程不安全) * */ public class Person2 { private String name; private static Person2 per; //构造函数私有化 private Person2() { } public String getName() { return name; } public void setName(String name) { this.name = name; } //提供一个全局的静态方法 public static Person2 getPerson2Instance() { //因为new也是需要时间的,在多线程的情况下会出现第一个new未执行完,多次new的情况 if(null == per) { per = new Person2(); } return per; } }
package test.com.singleton; /** * 双重检查 (线程安全的) * */ public class Person3 { private String name; private static Person3 per; //构造函数私有化 private Person3() { } public String getName() { return name; } public void setName(String name) { this.name = name; } //提供一个全局的静态方法 public static Person3 getPerson3Instance() { if(null == per) { //加锁的意义在于确保第一次new执行完 synchronized(Person3.class) { if(null == per) { per = new Person3(); } } } return per; } }
package test.com.singleton; /** * 测试 * */ public class Main { public static void main(String[] args) { Person per = Person.getPersonInstance(); Person per1 = Person.getPersonInstance(); per.setName("李青"); per1.setName("李小青"); System.out.println(per.getName());//李小青 System.out.println(per1.getName());//李小青 System.out.println(per == per1); Person2 per3 = Person2.getPerson2Instance(); Person2 per4 = Person2.getPerson2Instance(); per.setName("赵青"); per1.setName("赵小青"); System.out.println(per.getName());//赵小青 System.out.println(per1.getName());//赵小青 System.out.println(per3 == per4); } }