单例模式--来点新写法

Posted 微服务与大数据笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式--来点新写法相关的知识,希望对你有一定的参考价值。

常见到的饿汉模式单例,懒汉模式单例,区别就在于实例化对象,前者是类一加载的时候就初始化对象,后者是类被调用的时候,才初始化对象。

但今天要说的是,在并发情况下,如何保证并发安全的前提下,提高并发效率的使用。

对着代码分析:

常见高并发情境下的单例模式实现:

  1. public class UserService {


  2.    private static volatile UserService instance = null;


  3.    private UserService(){}


  4.    public static UserService getInstance(){

  5.        if(instance == null){

  6.            synchronized (UserService.class){

  7.                if(instance == null){

  8.                    return new UserService();

  9.                }

  10.            }

  11.        }

  12.        return instance;

  13.    }


  14.    public String getUserInfo(){

  15.        return "tangyuan";

  16.    }

  17. }

# 这里采用懒汉模式,即第3行,构建的空对象。当对象被调用的时候才 new 对象。

第5行,构造函数私有化。这样在其他地方就不能直接  new  UserService()对象,必须通过getInstance() 方法,获取对象。

第3行,先定义一个私有空对象,注意这里使用  volatile  修饰了instance,为了保证并发时,instance对象在主存中的可视性,保证先行发生关系(happens-before relationship),对于instance,所有的写(write)都将先行发生于读(read),注意,volatile不能保证原子性。

第8行,第一重校验,instance是否为null,并发时,可能会已被实例化,则不需要进入synchronized 修饰的代码块中,实例化。

第10行,第二重校验:并发时,可能可能A请求刚刚进入第10行,但实际上B请求先行释放锁,已new UserService() 。





上述写法很麻烦,还需要考虑各种锁的问题,实际上我们可以使用枚举的方式,代码简单,有效。如下:

  1. public enum EasySingleton {

  2.    INSTANCE;


  3.    public String getUserInfo(){

  4.        return "tangyuan";

  5.    }

  6. }

其实,1行代码就解决问题了。

有同学会问,我怎么调用它呢。

如下:

public class Test {

   public static void main(String[] args) {

       EasySingleton easySingleton = INSTANCE;

       System.out.println(easySingleton.getUserInfo());

   }

}



我再推荐另一种写法,这个没查到相关资料,但是在和同事讨论下,认为可行的一种方案,如果有同学认为有歧义,还请指正。

        实际上,现在大部分基于Java实现的产品,都会使用Spring 去管理bean。  其Bean 的生命周期,也由Spring 的容器进行管理。 Bean定义中,默认其bean 是单例的。所以,直接如下写法,在需要调用该Bean的时候,直接注入即可。

优点在于:1.不用我们自己维护单例 的生命周期及其实现。  2.解耦和,单例模式最大的弊端,我认为其扩展性太弱,耦合性太强。所有使用的地方,都需要调用getInstance()方法。


@Component

public class SpringSingleTone {

   public String getUserInfo(){

       return "tangyuan";

   }

}

如有错误,欢迎指正!


以上是关于单例模式--来点新写法的主要内容,如果未能解决你的问题,请参考以下文章

模式--单例模式8种写法

单例模式写法

单例模式的五种写法

单例模式的常用写法

单例模式(下)---聊一聊单例模式的几种写法

设计模式单例模式——单例有几种写法?