设计模式-单例模式JAVA实现

xiaoemo0 2020-04-08

单例模式其实是一种面向底层的开发模式,业务里能用到的环境不是很多。这里权且以项目启动时获取仓库信息做示例。

一,饿汉模式,在项目一启动的时候就将所需要的对象实例化出来。虽然传说中可能会占用内存不一定会用到,但实际上写一个不会被用到的例的可能性极小,不过不排除一些业务类可能会因为业务的变更迁移而被废掉,这么看来还是有些道理的。

饿汉式的单例模式是线程安全的,因为在发起多线程之前这个对象就已经存在了
package Singleton;

/**

  • 单例模式,饿汉式
  • @author
  • */
    public class WmsSingleton {

    //只在这里创建一次,是线程安全的
    private static WmsSingleton singleton = new WmsSingleton();

    private WmsSingleton() {}

    public static WmsSingleton getInstance() {

    System.out.println("获取对象前对象信息:"+singleton);
    return singleton;
    }
    }

一般的懒汉式不一定线程安全,所谓的线程安全,简略来讲只要你要对类的静态常量有修改的动作,那就可能会涉及到非线程安全

package Singleton;

/**

  • 单例模式,懒汉式
  • @author
  • */
    public class WmsLazySingleton {

    private static WmsLazySingleton singleton;

    private WmsLazySingleton() {}

    public static WmsLazySingleton getInstance() {

    if (singleton == null) {
         System.out.println("获取对象前对象信息:"+singleton);         
         singleton = new WmsLazySingleton();
         System.out.println("获取对象后对象信息:"+singleton);
     }
     return singleton;

    }
    }

既然一般的懒汉式可能涉及到线程安全问题,那么可以考虑对相应的方法块加一下同步锁,来解决这个问题。这里同步锁锁定的对象一定不能是null

可以想象成你无法对一个虚空加锁,必须要有一个实体,锁才能起到作用
package Singleton;

/**

  • 单例模式,饱汉式+synchronized锁,保证线程安全
  • @author
  • */
    public class WmsLazySyncSingleton {

    private static WmsLazySyncSingleton lazySyncSingleton = null;

    private static Object lock = new Object();

    private WmsLazySyncSingleton(){}

    public static WmsLazySyncSingleton getInstance(){

    //加同步锁
    synchronized(lock) {
    
        if (lazySyncSingleton == null) {
    
            lazySyncSingleton =  new WmsLazySyncSingleton();
        }
    }
    return lazySyncSingleton;

    }

}

以静态内部类的方式来实现懒汉式。这是基于JAVA加载静态内部类的时机来进行实现的
package Singleton;

/**

  • 静态内部类方式实现
  • @author
  • */
    public class WmsStaticClassSingleton {

    //静态内部类初始化对象
    private static class StaticClassSingleton{

    private static WmsStaticClassSingleton staticClassSingleton = new WmsStaticClassSingleton();

    }

    private WmsStaticClassSingleton(){}

    public static WmsStaticClassSingleton getInstance(){
    return StaticClassSingleton.staticClassSingleton;
    }
    }

相关推荐