文章目录
前言
单例模式:
- 是在整个软件生命周期中,值存在一个实例。使用单例模式可以提供系统性能。属于
创建者
。 - 使用场景:频繁创建和销毁的对象、创建对象耗时过长或耗费资源过多的对象。
一、单例代码实现
1.主程序代码
代码如下(示例):
/**
* 保证整个软件系统中,对某个类智能存在一个对象实例
* 属于创建者模式
*/publicclassSingletonClient{/**
* 1. 饿汉式(静态常量)
* 2. 饿汉式(静态代码块)
* 3. 懒汉式(线程安全、同步方法)
* 4. 双重检查
* 5. 静态内部类
* 6. 枚举
*/publicstaticvoidmain(String[] args){staticFinal();staticCode();synchronizedMethod();synchronizedCode();staticInsideClass();enumInstance();}//枚举publicstaticvoidenumInstance(){SingletonEnum singleton1=SingletonEnum.INSTANCE;SingletonEnum singleton2=SingletonEnum.INSTANCE;System.out.println("singleton1 hash code = "+ singleton1.hashCode());System.out.println("singleton2 hash code = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2 is "+(singleton1== singleton2));}//饿汉式(静态常量)publicstaticvoidstaticFinal(){SingletonStaticFinal singleton1=SingletonStaticFinal.getInstance();SingletonStaticFinal singleton2=SingletonStaticFinal.getInstance();System.out.println("singleton1 hash code = "+ singleton1.hashCode());System.out.println("singleton2 hash code = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2 is "+(singleton1== singleton2));}//饿汉式(静态代码块)publicstaticvoidstaticCode(){SingletonStaticCode singleton1=SingletonStaticCode.getInstance();SingletonStaticCode singleton2=SingletonStaticCode.getInstance();System.out.println("singleton1 hash code = "+ singleton1.hashCode());System.out.println("singleton2 hash code = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2 is "+(singleton1== singleton2));}//懒汉式(同步方法)publicstaticvoidsynchronizedMethod(){SingletonSynchronizedMethod singleton1=SingletonSynchronizedMethod.getInstance();SingletonSynchronizedMethod singleton2=SingletonSynchronizedMethod.getInstance();System.out.println("singleton1 hash code = "+ singleton1.hashCode());System.out.println("singleton2 hash code = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2 is "+(singleton1== singleton2));}//懒汉式(同步代码块)publicstaticvoidsynchronizedCode(){SingletonSynchronizedCode singleton1=SingletonSynchronizedCode.getInstance();SingletonSynchronizedCode singleton2=SingletonSynchronizedCode.getInstance();System.out.println("singleton1 hash code = "+ singleton1.hashCode());System.out.println("singleton2 hash code = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2 is "+(singleton1== singleton2));}//懒汉式(静态内部类)publicstaticvoidstaticInsideClass(){SingletonStaticInsideClass singleton1=SingletonStaticInsideClass.getInstance();SingletonStaticInsideClass singleton2=SingletonStaticInsideClass.getInstance();System.out.println("singleton1 hash code = "+ singleton1.hashCode());System.out.println("singleton2 hash code = "+ singleton2.hashCode());System.out.println("singleton1 = singleton2 is "+(singleton1== singleton2));}
2.静态常量(static final)
代码实现
/**
* 静态常量:单例
* instance:在类装载到方法区时,静态常量会自动创建。避免了多线程.
* 不好的地方是如果不使用,就会浪费内存。
*/publicclassSingletonStaticFinal{privatestaticfinalSingletonStaticFinal instance=newSingletonStaticFinal();/**
* 私有化是为了防止,外部类创建。
*/privateSingletonStaticFinal(){}publicstaticSingletonStaticFinalgetInstance(){return instance;}}
3. 静态代码块(static code)
代码如下(示例):
/**
* 静态代码块:单例
* instance:在类装载到方法区时,会执行静态代码块。避免了多线程.
* 不好的地方是如果不使用,就会浪费内存。
*/publicclassSingletonStaticCode{privatestaticSingletonStaticCode instance;//静态代码块static{
instance=newSingletonStaticCode();}/**
* 私有化是为了防止,外部类创建。
*/privateSingletonStaticCode(){}publicstaticSingletonStaticCodegetInstance(){return instance;}}
4. 同步静态方法(synchronized static method)
代码如下(示例):
/**
* 同步静态方法:单例
* instance:在JAVA堆上创建,只有在使用的时候会创建。会出现多线程问题.
* 需要添加同步(synchronized)方法
* 只有在使用的时候创建,避免浪费内存。
* 出现问题:效率过低,每次调用都是同步
*/publicclassSingletonSynchronizedMethod{privatestaticSingletonSynchronizedMethod instance;/**
* 私有化是为了防止,外部类创建。
*/privateSingletonSynchronizedMethod(){}/**
* 每次执行,都是同步执行。导致效率过低
*/publicsynchronizedstaticSingletonSynchronizedMethodgetInstance(){if(instance==null){
instance=newSingletonSynchronizedMethod();}return instance;}}
5. 双重检查(double check)
代码如下(示例):
/**
* 双重检查:单例
* instance:在JAVA堆上创建,只有在使用的时候会创建。会出现多线程问题.
* 需要添加同步(synchronized)方法
* 只有在使用的时候创建,避免浪费内存。
* 推荐使用
*/publicclassSingletonSynchronizedCode{privatestaticvolatileSingletonSynchronizedCode instance;/**
* 私有化是为了防止,外部类创建。
*/privateSingletonSynchronizedCode(){}//双重检查,publicstaticSingletonSynchronizedCodegetInstance(){if(instance==null){synchronized(SingletonStaticCode.class){//如果不检查,多线程情况下会创建多个实例if(instance==null){
instance=newSingletonSynchronizedCode();}}}return instance;}}
6. 静态内部类(static inside class)
代码如下(示例):
/**
* 静态内部类:单例
* 推荐使用
*/publicclassSingletonStaticInsideClass{privatestaticSingletonStaticInsideClass instance;static{
instance=newSingletonStaticInsideClass();}/**
* 私有化是为了防止,外部类创建。
*/privateSingletonStaticInsideClass(){}privatestaticclassSignleton{privatestaticfinalSingletonStaticInsideClass INSTANCE=newSingletonStaticInsideClass();}publicstaticSingletonStaticInsideClassgetInstance(){//当静态方法调用是,才会加载内部静态类。//而内部静态类,在加载到方法区的时候会创建静态常量,避免多线程创建。returnSignleton.INSTANCE;}}
总结
推荐使用:
- 双重检查
- 静态内部类
- 枚举:还能有效防止反序列化。