当前位置: 首页 > 编程笔记 >

图文结合讲解Java单例模式

司毅庵
2023-03-14
本文向大家介绍图文结合讲解Java单例模式,包括了图文结合讲解Java单例模式的使用技巧和注意事项,需要的朋友参考一下

PS:首先我们要先知道什么是单例,为什么要用单例,用的好处是什么等问题来看。

1:java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例、饿汉式单例

单例模式有以下特点:

  1、单例类只能有一个实例
  2、单例类必须自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

2:懒汉式

先把单例类写出来

public class SingletonTest { 
  //懒汉式单例类.在第一次调用的时候实例化自己  
  private SingletonTest() {} 
    private static SingletonTest single=null; 
    //静态工厂方法  
    public static SingletonTest getInstance() { 
       if (single == null) {  
         single = new SingletonTest(); 
         System.out.println("创建一次"); 
       }  
      return single; 
    } 
     
    public void show(){ 
      System.out.println("我是show"); 
    } 
 
} 

这里直接上代码,代码中有详解

public class SingletonTest2 { 
 
  public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    //故意写获取两次,创建两个对象 
    SingletonTest singleton=SingletonTest.getInstance(); 
    SingletonTest singleton2=SingletonTest.getInstance(); 
     
    //Singleton对象只创建一次,但是写两次还是可以的,而且方法都是可以调用的,但是看下面 
    singleton.show(); 
    singleton2.show(); 
     
    //两个对象的表现形式一样 
    if(singleton == singleton2){ 
      System.out.println("该对象的字符串表示形式:"); 
      System.out.println("singleton :"+singleton.toString()); 
      System.out.println("singleton2:"+singleton2.toString()); 
    } 

由上面的图可以看出就算多创建几个对象,在底部也是只有一个singleton对象实例,而且创建出来的对象的字符串表现形式也是一样的,有的人肯定有疑问,那平常两个对象是什么样子的呢,我下面给你解释说明,在这之前我写说一下这个懒汉式需要注意的地方,它是线程不安全的,并发环境下很可能出现多个Singleton实例,有很多方法可以解决,比如说同步锁,静态内部类等,这里主要说静态内部类,这个比较好点,

public class Singleton3 {  
  private static class SingletonHolder {  
    private static final Singleton3 INSTANCE = new Singleton3();  
  }  
  private Singleton3 (){}  
  public static final Singleton3 getInstance() {  
    System.out.println("singleton创建"); 
    return SingletonHolder.INSTANCE;  
  }  
}  

调用:

Singleton3 singleton3=Singleton3.getInstance(); 
    Singleton3 singleton4=Singleton3.getInstance(); 
    if(singleton3 == singleton4){ 
      System.out.println("该对象的字符串表示形式:"); 
      System.out.println("singleton3:"+singleton3.toString()); 
      System.out.println("singleton4:"+singleton4.toString()); 
    } 

结果图:

这里我也是创建了两个对象来说明,神奇的是打印了两次singleton创建,这难道是又创建成功了的对象吗?答案是:虽然打印了两次,对象名也有两个,但是该对象的字符串表示形式还是一样的,而且大家都知道static的用法,就是在类被加载的同时该singleton对象就已经被创建,后期不会再被创建,就算后期自己又调用了getInstance()方法,但底层还是公用的一个Singleton对象.

同样,我写了一个普通的类,来同时创建两个对象,并且打印他们的toString()方法,如下:

QuBie qb1=new QuBie(); 
    QuBie qb2=new QuBie(); 
    if(qb1 == qb2){ 
      System.out.println("该对象的字符串表示形式:"); 
      System.out.println("singleton3:"+qb1.toString()); 
      System.out.println("singleton4:"+qb2.toString()); 
    }else{ 
      System.out.println("该对象的字符串表示形式:"); 
      System.out.println("singleton3:"+qb1.toString()); 
      System.out.println("singleton4:"+qb2.toString()); 
    } 


由此可看出来对象的字符串表示形式是不一样的

3:饿汉式单例

饿汉式单例类.在类初始化时,已经自行实例化  

public class Singleton1 { 
 private Singleton1() {} 
 private static final Singleton1 single = new Singleton1(); 
 //静态工厂方法  
 public static Singleton1 getInstance() { 
   return single; 
 } 
} 

因为这本身就是static修饰的方法,所以是在类加载的时候被创建,后期不会再改变,所以线程是安全的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍简单讲解在Java编程中实现设计模式中的单例模式结构,包括了简单讲解在Java编程中实现设计模式中的单例模式结构的使用技巧和注意事项,需要的朋友参考一下 1. 模式介绍 模式的定义 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 模式的使用场景 确保某个类有且只有一个对象的场景,例如创建一个对象需要消耗的资源过多,如要访问 IO 和数据库等资源。 2. UML类图

  • 本文向大家介绍C#设计模式之单例模式实例讲解,包括了C#设计模式之单例模式实例讲解的使用技巧和注意事项,需要的朋友参考一下 前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高、保证代码可靠性。所谓设计模式,我找了下定义:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工

  • 线性DP,所谓线性DP,就是指我们的递归方程有一个明显的线性关系的,有可能是一维线性的,也可能是二维线性的。 例题一:大盗阿福 题目:阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。 这条街上一共有 NN 家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。 作为一向谨慎作案的大盗,阿福不愿意冒着

  • 本篇通过图文解析讲述插头DP的内容,结合前面的状态压缩DP知识,以及前置知识:哈希,方便大家能快速理解。 在阐述什么是插头DP之前,我们先了解插头DP有什么用?插头DP是用来解决一类网格图上的连通性问题的强力工具。题目的特征是给定的网格非常小(这个特征类似状压DP)。事实上,插头DP也可以看做是状压DP的一种。 一、什么是插头DP 很显然,是一个关于插头的动态规划。那么,什么是插头呢? 如图我们在

  • 本文向大家介绍jQuery UI Draggable + Sortable 结合使用(实例讲解),包括了jQuery UI Draggable + Sortable 结合使用(实例讲解)的使用技巧和注意事项,需要的朋友参考一下 工作中需要将一个左边的设计好的控件,拖拽到右边的面板中,同时保持右边面板中的控件自由排序,这时候就需要及支持拖拽又支持排序的操作了, Demo截图:从左边控件拖到右边区域

  • 本文向大家介绍java设计模式-代理模式(实例讲解),包括了java设计模式-代理模式(实例讲解)的使用技巧和注意事项,需要的朋友参考一下 代理模式是java最常见的设计模式之一。spring的aop就是使用了代理模式。 一般而言,代理模式分为静态代理和动态代理两种。 作为结构类的设计模式,作用在于不修改类内部代码的情况下,对类进行拓展,是对继承机制的一种补充。 eg :下面就用户登录这个例子实现