单例模式

public class Singleton {

    static class Singleton1 {
        private static Singleton1 singleton1 = new Singleton1();

        private Singleton1() {
        }

        public static Singleton1 getInstance() {
            return singleton1;
        }
    }

    static class Singleton2 {
        private static Singleton2 singleton2 = null;

        private Singleton2() {
        }

        public static Singleton2 getInstance() {
            if (singleton2 == null) {
                singleton2 = new Singleton2();
            }
            return singleton2;
        }
    }

    static class Singleton3 {
        private static Singleton3 singleton3 = null;

        private Singleton3() {
        }

        public static synchronized Singleton3 getInstance() {
            if (singleton3 == null) {
                singleton3 = new Singleton3();
            }
            return singleton3;
        }
    }

    static class Singleton4 {
        private static Singleton4 singleton4 = null;

        private Singleton4() {
        }

        public static Singleton4 getInstance() {
            if (singleton4 == null) {
                synchronized (Singleton4.class) {
                    if (singleton4 == null) {
                        singleton4 = new Singleton4();
                    }
                }
            }
            return singleton4;
        }
    }
    static class Singleton5{
        private static volatile Singleton5 singleton5 = null;
        private Singleton5() {
        }

        public static Singleton5 getInstance() {
            if (singleton5 == null) {
                synchronized (Singleton5.class) {
                    if (singleton5 == null) {
                        singleton5 = new Singleton5();
                    }
                }
            }
            return singleton5;
        }
    }

    static class Singleton6 {
        private Singleton6() {
        }

        static class Singleton6Holder {
            private static Singleton6 singleton6 = new Singleton6();
        }

        public static Singleton6 getInstance(){
            return Singleton6Holder.singleton6;
        }

    }

    enum Singleton7 {
        ins;

        public int max(int a, int b) {
            if (a > b) {
                return a;
            }
            return b;
        }
    }
}

第一种单例模式 饿汉式(推荐使用)

static class Singleton1 {
        private static Singleton1 singleton1 = new Singleton1();

        private Singleton1() {
        }

        public static Singleton1 getInstance() {
            return singleton1;
        }
    }

最简单的写法,缺点在于实例在类初始化的时候就创建了,如果在整个项目中都没有使用到该类,就会创建内存空间的浪费。

不适用于大对象的创建。

第二种单例模式 线程不安全的懒汉式

static class Singleton2 {
        private static Singleton2 singleton2 = null;

        private Singleton2() {
        }

        public static Singleton2 getInstance() {
            if (singleton2 == null) {
                singleton2 = new Singleton2();
            }
            return singleton2;
        }
    }

解决了懒汉式在类初始化的时候就创建实例的问题,然而只能在单线程中使用,在多线程中使用如果多个线程同时进入if语句中,就可能出现创建多个实例的问题。

第三种单例模式 线程安全的懒汉式

static class Singleton3 {
        private static Singleton3 singleton3 = null;

        private Singleton3() {
        }

        public static synchronized Singleton3 getInstance() {
            if (singleton3 == null) {
                singleton3 = new Singleton3();
            }
            return singleton3;
        }
    }

解决了线程不安全的懒汉式可能出现的问题,可以在多线程中使用。缺点在于synchronized关键字会强制一次只能让一个线程进入方法中,其他线程不得不阻塞等待该线程退出方法。

第四种单例模式 双重检查锁单例

static class Singleton4 {
        private static Singleton4 singleton4 = null;

        private Singleton4() {
        }

        public static Singleton4 getInstance() {
            if (singleton4 == null) {
                synchronized (Singleton4.class) {
                    if (singleton4 == null) {
                        singleton4 = new Singleton4();
                    }
                }
            }
            return singleton4;
        }
    }

解决了线程安全的懒汉式出现的问题。缺点在于 JVM 在执行对引用赋值时并不是一个原子操作。步骤一:在堆中为 Singleton 分配内存空间,步骤二:对 Sngleton 执行初始化操作, 步骤三:将引用变量指向该实例所对应的内存地址以完成赋值。而 JVM 对这一步进行了优化,使得步骤二和步骤三可以不按顺序执行。所以就有可能出现一个线程在执行了步骤一之后执行了步骤三,然后另一个线程调用了该方法,此时 instance 引用变量不为空,然而 Singleton 实例还没有完成初始化,就会造成非单例。

第五种单例模式 cpu安全的双重检查锁单例(推荐使用)

static class Singleton5{
        private static volatile Singleton5 singleton5 = null;
        private Singleton5() {
        }

        public static Singleton5 getInstance() {
            if (singleton5 == null) {
                synchronized (Singleton5.class) {
                    if (singleton5 == null) {
                        singleton5 = new Singleton5();
                    }
                }
            }
            return singleton5;
        }
    }

解决了双重检查锁出现的问题,volatile关键字能够禁止指令重排,保证在写操作没有完成之前不能调用读操作。

第六种单例模式 静态内部类单例(推荐使用)

 static class Singleton6 {
        private Singleton6() {
        }

        static class Singleton6Holder {
            private static Singleton6 singleton6 = new Singleton6();
        }

        public static Singleton6 getInstance(){
            return Singleton6Holder.singleton6;
        }

    }

这种写法的好处是充分利用了静态内部类的特点,它的初始化操作跟外部类是分开的。在没有调用 getInstance() 方法之前,静态内部类不会进行初始化,在第一次调用该方法后就生成了唯一一个实例

第七种单例模式 枚举式单例(推荐使用)

enum Singleton7 {
        ins;

        public int max(int a, int b) {
            if (a > b) {
                return a;
            }
            return b;
        }
    }

充分利用枚举类的特性,只定义了一个实例,且枚举类是天然支持多线程的。

 

单例模式应用的场景一般发现在以下条件下:

(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件,应用配置。

(2)控制资源的情况下,方便资源之间的互相通信。如线程池等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值