Java三种单例模式的实现和优劣对比

单例(singleton):只允许创建一个该类的对象。

① 单例模式:饿汉式(线程安全、占资源)

  • 天生线程安全(无锁)、类加载时创建(不用也会被创建,占用资源
public class TestSingleton {
    public static void main(String[] args) {
        Singleton1 s1 = Singleton1.getInstance();
        Singleton1 s11 = Singleton1.getInstance();
        System.out.println(s1); // Singleton1@7852e922
        System.out.println(s11); // Singleton1@7852e922
    }
}

class Singleton1 {
    // 私有静态常量引用,类加载执行就1份、不可调用、不可修改(始终单例)
    private static final Singleton1 instance = new Singleton1();
    // 私有构造,不可直接new对象
    private Singleton1() {}
    // 静态方法,类名直接调用,返回私有静态常量引用
    public static Singleton1 getInstance() {
        return instance;
    }
}

② 单例模式:懒汉式(不安全、需要同步)

  • 天生线程不安全(需同步锁、效率低)、使用时才创建
public class TestSingleton {
    public static void main(String[] args) {        
        Singleton2 s2 = Singleton2.getInstance();
        Singleton2 s22 = Singleton2.getInstance();
        System.out.println(s2); // Singleton2@4e25154f
        System.out.println(s22); // Singleton2@4e25154f
    }
}

class Singleton2 {
    // 私有静态引用,类加载执行就1份、不可调用
    private static Singleton2 instance = null;
    // 私有构造,不可直接new对象
    private Singleton2() {}
    // 同步锁、静态方法获取类的对象(引用为空则new,不为空则返回自身,始终单例)
    public synchronized static Singleton2 getInstance() {
        return instance == null ? instance = new Singleton2() : instance;
    }
}

③ 单例模式:懒汉式(线程安全,静态内部类)

  • 天生线程安全(无锁),使用时才创建(静态内部类)
public class TestSingleton {
    public static void main(String[] args) {
        Singleton3 s3 = Singleton3.getInstance();
        Singleton3 s33 = Singleton3.getInstance();
        System.out.println(s3); // Singleton3@70dea4e
        System.out.println(s33); // Singleton3@70dea4e
    }
}

class Singleton3 {
    // 私有构造,不可直接new对象
    private Singleton3() {}
    // 静态内部类,不依赖外部类,使用时才需要创建,可独立创建
    // 内部类中静态常量引用,一旦创建内部类,属性则不可修改(始终单例)
    private static class Holder {
        static final Singleton3 instancce = new Singleton3();
    }
    // 静态方法,获取内部类中创建的外部类对象的常量引用
    public static Singleton3 getInstance() {
        return Holder.instancce;
    }
}

你可能感兴趣的:(Java三种单例模式的实现和优劣对比)