单例模式的八种方式

  1. 饿汉式(静态常量)
  2. 饿汉式(静态代码块)
  3. 懒汉式(线程不安全)
  4. 懒汉式(线程安全,同步方法)
  5. 懒汉式(线程安全,同步代码块)
  6. 双重检查
  7. 静态内部类
  8. 枚举

饿汉式(静态常量)

步骤:

  1. 构造器私有化

目的:放置外部通过new的方式创建对象

  1. 在类的内部创建对象

因为禁止外部创建对象,所以在类的内部创建对象

  1. 对外暴露一个静态的公共方法,getInstance()
  2. 代码实现
  1. public class singleton01 {
  2. public static void main(String[] args) {
  3. Singleton instance = Singleton.getInstance();
  4. Singleton instance1 = Singleton.getInstance();
  5. //测试1证明两个实例是一样的
  6. System.out.println(instance==instance1);//true
  7. //测试2通过hashCode
  8. System.out.println(instance.hashCode()==instance1.hashCode());
  9. }
  10. }
  11. class Singleton{
  12. //1.构造器私有化
  13. private Singleton(){}
  14. //2.在类的内部创建对象实例
  15. private final static Singleton instance=new Singleton();
  16. //3.提供一个公有的静态对象,返回实例对象
  17. public static Singleton getInstance(){
  18. return instance;
  19. }
  20. }
  1. 优缺点

优点:写法比较简单,就是在类装载的时候完成了实例化,避免了线程同步的问题
缺点:在类装载的时候就完成了实例化,没有达到Lazy Loading(懒加载)的效果,如果从始至终从未使用 过这个实例,则会造成内内存的浪费

  1. 说明:这种方式是记忆classloader机制,避免了多线程的同步问题,不过,instance在类装载的时候就实例化了,在单例模式中,大多数都是调用getInstance方法,但是导致类装载的原因有很多种,因此,不能确定有其他方式(或着其他的静态方法)导致类装载,这时候初始化instance就没有达到Lazy Loading(懒加载)的效果
  2. 结论:这种单例模式可以用,但是可能造成内存浪费

饿汉式(静态代码块)

  1. 代码实现
  1. public class singleton02 {
  2. public static void main(String[] args) {
  3. Singleton instance = Singleton.getInstance();
  4. Singleton instance1 = Singleton.getInstance();
  5. //测试1证明两个实例是一样的
  6. System.out.println(instance == instance1);//true
  7. //测试2通过hashCode
  8. System.out.println(instance.hashCode() == instance1.hashCode());
  9. }
  10. }
  11. class Singleton {
  12. //1.构造器私有化
  13. private Singleton() {
  14. }
  15. //2.在类的内部创建对象实例
  16. private static Singleton instance;
  17. static {//在静态代码块中,创建单例对象
  18. instance = new Singleton();
  19. }
  20. //3.提供一个公有的静态对象,返回实例对象
  21. public static Singleton getInstance() {
  22. return instance;
  23. }
  24. }
  1. 优缺点:

这种方式和饿汉式(静态常量)方式是一样的,只不过将类的实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和饿汉式(静态常量)一样

  1. 结论:这种单例模式可以用,但是可能造成内存浪费