一,单例模式

1-1 饿汉式(静态常量)

  1. 代码实现

    public class Singleton01 {
        // 1,私有化构造方法
        private Singleton01() {
    
        }
    
        // 2,创建实例对象
        private final static Singleton01 instance = new Singleton01();
    
        // 3,对外提供获取实例的方法
        public static Singleton01 getInstance() {
            return instance;
        }
    
    }
    
  2. 优缺点

    • 优点:实现方式简单,实例对象在类加载的时候完成实例化操作,避免了多线程的问题。
    • 缺点:没有达到Lazy loading,如果该实例对象一直没有被使用,则会造成内存浪费。

1-2 饿汉式(静态代码块)

  1. 代码实现

    public class SingletonType02 {
        // 1,私有化构造方法
        private SingletonType02() {
    
        }
    
        // 2,创建实例对象
        private static SingletonType02 instance;
        static {
            instance = new SingletonType02();
        }
    
        // 3,对外提供获取实例的方法
        public static SingletonType02 getInstance() {
            return instance;
        }
    
    }
    
  2. 优缺点

    和静态常量的方式唯一的区别就是:将实例化操作放在了静态代码块中,所以和静态常量方式的优缺点相同。

1-3 懒汉式(线程不安全)

  1. 代码实现

    public class SingletonType03 {
        // 1,私有化构造方法
        private SingletonType03() {
    
        }
    
        // 2,定义实例对象
        private static SingletonType03 instance;
    
        // 3,对外提供获取实例的方法
        public static SingletonType03 getInstance() {
            // 获取实例对象时,判断实例对象是否为空,为空时才对其进行实例化
            if(instance == null) {
                instance = new SingletonType03();
            }
            return instance;
        }
    
    }
    
  2. 优缺点

    • 优点:实现了Lazy loading

    • 缺点:线程不安全。在多线程的情况下,可能会生成多个实例化对象。所以,在开发中,不要使用该方式

      例如,当一个线程在执行if(instance == null) 时,另外一个线程也执行该代码,最终会生成两个实例化对象。

      public class MultiThreadTest implements Callable<SingletonType03> {
      
          public static void main(String[] args) throws InterruptedException, ExecutionException {
      
              MultiThreadTest mt = new MultiThreadTest();
              FutureTask<SingletonType03> ft = new FutureTask<>(mt);
              new Thread(ft, "子线程").start();
      
              SingletonType03 instance1 = SingletonType03.getInstance();
              SingletonType03 instance2 = ft.get();
      
              System.out.println("instance1's hashcode:" + instance1.hashCode());
              System.out.println("instance2's hashcode:" + instance2.hashCode());
      
          }
      
          @Override
          public SingletonType03 call() throws Exception {
              return SingletonType03.getInstance();
          }
      }
      
      

1-4 懒汉式(线程安全,同步方法)

  1. 代码实现

    public class SingletonType04 {
        // 1,私有化构造方法
        private SingletonType04() {
    
        }
    
        // 2,定义实例对象
        private static SingletonType04 instance;
    
        // 3,对外提供获取实例的方法
        public static synchronized SingletonType04 getInstance() {
            // 获取实例对象时,判断实例对象是否为空,为空时才对其进行实例化
            if(instance == null) {
                instance = new SingletonType04();
            }
            return instance;
        }
    
    }
    
  2. 优缺点

    • 优点:线程安全
    • 缺点:效率低,每次获取instance时,都要进行线程同步。

1.5 双重检查

  1. 代码实现

    public class SingletonType05 {
        // 1,私有化构造方法
        private SingletonType05() {
    
        }
    
        // 2,定义实例对象
        private static volatile SingletonType05 instance;
    
        // 3,对外提供获取实例的方法
        public static SingletonType05 getInstance() {
            // 获取实例对象时,判断实例对象是否为空,为空时才对其进行实例化
            if(instance == null) {
                synchronized (SingletonType05.class) {
                    // 再次检查实例对象是否为空
                    if(instance == null) {
                        instance = new SingletonType05();
                    }
                }
            }
            return instance;
        }
    
    }
    
  2. 优缺点

    • 优点:实现了Lazy loading,线程安全,保证了效率。

1-6 静态内部类

  1. 代码实现

    public class SingletonType06 {
        // 1,私有化构造方法
        private SingletonType06() {
    
        }
    
        // 2,定义实例对象
        private static volatile SingletonType06 instance;
    
        // 3,定义静态内部类
        // 3-1,静态内部类SingleInstance不会被立即加载,只有在调用getInstance方法时,才会被加载
        // 3-2,在加载静态内部类时,其静态属性INSTANCE会被初始化,且JVM保证了线程安全
        private static class SingleInstance {
            private static final SingletonType06 INSTANCE = new SingletonType06();
        }
    
        // 3,对外提供获取实例的方法
        public static SingletonType06 getInstance() throws InterruptedException {
            return SingleInstance.INSTANCE;
        }
    
    }
    
  2. 优缺点

    • 优点:实现了Lazy loading,线程安全,效率高

1.7 枚举方式

  1. 代码实现

    public class SingletonType07 {
        public static void main(String[] args) {
            Singleton instance1 = Singleton.INSTANCE;
            Singleton instance2 = Singleton.INSTANCE;
            System.out.println("instance1's hashcode:" + instance1.hashCode());
            System.out.println("instance2's hashcode:" + instance2.hashCode());
        }
    
    }
    
    enum Singleton {
        INSTANCE;
        public void xxMethod () {
            System.out.println("xxMethod");
        }
    }
    
  2. 优缺点

    • 优点:避免了线程同步问题,还能防止反序列化重新创建新的对象。
posted @ 2022-03-19 23:13  kewen  阅读(37)  评论(0)    收藏  举报