你真的了解java单例模式了吗?

  


  

  

最近在学习设计模式,在看到单例模式的时候,我一开始以为直接很了解单例模式了,实现起来也很简单,但是实际上单例模式有着好几个变种,并且多线程中涉及到线程安全问题,那么本文我们就来好好聊聊单例模式,说一下经典三种实现方式:饿汉式,懒汉式,登记式。并且解决掉多线程中可能出现的线程安全问题。

  


  

  

<强> 1。为什么要使用单例模式?

  

在我们日常的工作中,很多对象通常占用非常重要的系统资源,比如:IO处理,数据库操作等,那我们必须要限制这些对象只有且始终使用一个公用的实例,即单例。

  

<强> 2。单例模式的实现方式

  

构造函数私有化,防止其他类生成唯一公用实例外的实例。且单例类应该被定义为决赛,也就是说单例类不能被继承,因为如果允许继承那子类就都可以创建实例,违背了类唯一实例的初衷。
  

  

类中一个静态变量来保存单实例的引用。
  

  

一个共有的静态方法来获取单实例的引用。
  <强> 3。单例模式的UML类图

  

你真的了解java单例模式了吗?

  

<>强4。单例模式的经典实现方式

  
      <李>饿汉式:一开始就创建好实例,每次调用直接返回,经典的“拿空间换时间”。   <李>懒汉式:延迟加载,第一次调用的时候才加载,然后返回,以后的每次的调用就直接返回。经典”拿时间换空间”,多线程环境下要注意解决线程安全的问题。   <李>登记式:对一组单例模式进行的维护,主要是在数量上的扩展,通过线程安全的地图把单例存进的去,这样在调用时,先判断该单例是否已经创建,是的话直接返回,不是的话创建一个登记到地图中,再返回。   
  


  

  

<强> 1。单例类

        包com.hafiz.designPattern.singleton;/* *   *描述:单例模式,饿汉式   *由hafiz.zhang>   公开课DesignPatternTest {   @Test   公共空间testSingleton1 () {   System.out.println(“- - - - - - - - - - - - - - - - - -测试饿汉式单例模式开始- - - - - - - - - - - - - - - -”);   Singleton1 instance1=Singleton1.getInstance ();   System.out.println(“第二次获取实例”);   Singleton1 instance2=Singleton1.getInstance ();   System.out.println (“instance1和instance2是否为同一实例& # 63;”+ (instance1==instance2));   System.out.println(“- - - - - - - - - - - - - - - - - -测试饿汉式单例模式结束- - - - - - - - - - - - - - - -”);   }   }      

<强> 3。测试结果

  

你真的了解java单例模式了吗?

  


  

  

<强> 1。单例类

        包com.hafiz.designPattern.singleton;/* *   *描述:单例模式——懒汉式   *由hafiz.zhang>   公开课DesignPatternTest {   @Test   公共空间testSingleton2 () {   System.out.println(“- - - - - - - - - - - - - - - - - -测试懒汉式单例模式开始- - - - - - - - - - - - - - - -”);   Singleton2 instance1=Singleton2.getInstance ();   System.out.println(“第二次获取实例”);   Singleton2 instance2=Singleton2.getInstance ();   System.out.println (“instance1和instance2是否为同一实例& # 63;”+ (instance1==instance2));   System.out.println(“- - - - - - - - - - - - - - - - - -测试懒汉式单例模式结束- - - - - - - - - - - - - - - -”);   }   }      

<强> 3。测试结果

  

你真的了解java单例模式了吗?

  

细心的同学已经发现,这种实现方式,在多线程的环境中,是有线程安全安全问题的,有可能两个或多个线程判断实例都为null,然后创建了好几遍实例,不符合单例的思想,我们可以对它进行改进。

  


  

  

原理:使用JDK的同步同步代码块来解决懒汉式线程安全问题。

  

<强> 1。单例类

        包com.hafiz.designPattern.singleton;/* *   *描述:单例模式——懒汉式   *由哈菲兹。张alt="你真的了解java单例模式了吗? ">

  


  

  

原理:使JVM用隐含的同步和类级内部类来解决,JVM隐含的同步解决了多线程情况下线程安全的问题,类级内部类解决只有使用的时候才加载(延迟加载)的问题。

你真的了解java单例模式了吗?