确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例

1.1.1.懒汉式(非线程安全)

只有当调用getInstance()方法对象才会被实例化

  1. public class Singleton {
  2. /**
  3. * 私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载
  4. */
  5. private static Singleton instance = null;
  6. /**
  7. * 构造器私有化,防止被实例化
  8. */
  9. private Singleton() {
  10. }
  11. /**
  12. * 懒汉式静态工程方法,创建实例
  13. *
  14. * @return
  15. */
  16. public static Singleton getInstance() {
  17. if (instance == null) {
  18. instance = new Singleton();
  19. }
  20. return instance;
  21. }
  22. }

1.1.2.饿汉式(线程安全)

类一旦加载,就把单例初始化完成,保证getInstance()的时候,单例是已经存在

  1. public class Singleton {
  2. /**
  3. * 饿汉式,保证类加载时候,实例就已存在
  4. */
  5. private static Singleton instance = new Singleton1();
  6. /**
  7. * 对象私有化
  8. */
  9. private Singleton() {
  10. }
  11. public static Singleton getInstance() {
  12. return instance;
  13. }
  14. }

使用场景:
1.要求生成唯一序列号的环境;
2.在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;
3.创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;
4.需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式 (当然,也可以直接声明为static的方式)。

1.1.3.懒汉式(线程安全)

在getInstance()方法上加上synchronized关键字

  1. public class Singleton2 {
  2. /**
  3. * 懒汉式:初始化为null
  4. */
  5. private static Singleton2 instance = null;
  6. /**
  7. * 构造方法私有化
  8. */
  9. private Singleton2() {
  10. }
  11. public static synchronized Singleton2 getInstance() {
  12. if (instance == null) {
  13. instance = new Singleton2();
  14. }
  15. return instance;
  16. }
  17. }

1.1.4.懒汉式(线程安全,双重锁验证)

静态代码块的方式

  1. public class Singleton3 {
  2. // volatile 可以禁止 JVM 的指令重排
  3. private volatile static Singleton = null;
  4. /**
  5. * 构造方法私有化
  6. */
  7. private Singleton3() {
  8. }
  9. public static Singleton3 getInstance() {
  10. if (instance == null) {
  11. synchronized (Singleton3.class) {
  12. instance = new Singleton3();
  13. }
  14. }
  15. return instance;
  16. }
  17. }