专栏首页Android机器圈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修饰的方法,所以是在类加载的时候被创建,后期不会再改变,所以线程是安全的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据结构与算法----数学应用之一元多项式

    PS:上一篇说了线性表的顺序表和链式表表达,该片就写一下应用到现实数学中去,一元多项式的加减。

    cMusketeer
  • 数据结构与算法 -- 二叉树链式详解((非)/递归遍历,叶子个数,深度计算)

    PS:树型结构是一种重要的非线性数据结构,教科书上一般都是树与二叉树,由此可见,树和二叉树是有区别和联系的,网上有人说二叉树是树的一种特殊形式,但经过查资料,树...

    cMusketeer
  • 数据结构与算法----双向链表

    PS:前面已经说过线性表的两种表现形式,一种是顺序,另一种是链式,链式的一种普通表现形式就是加入一个指针,前一个的指针指向后一个结点的地址,那么还有一种形式就是...

    cMusketeer
  • SpringBoot启动加载类ApplicationRunner

    有时希望项目在启动的时候加载一些系统参数,就要用到ApplicationRunner

    用户2409797
  • 避开NullPointerException的10条建议

    NullPointerException应该是 Java 开发中最常出现的问题,也是 Java 程序员最容易犯的错误。虽然看起来是个小错误,但带来的影响却不小,...

    草捏子
  • Java8异步编程就是拽

    runAsync方法可以在后台执行异步计算,但是此时并没有返回值。持有一个Runnable对象。

    架构师修炼
  • java(3)——数据类型中的数值型的整数类型

    java的数据类型有两大类:基本数据类型和引用数据类型 基本数据类型分为数值型(数值型又分为整数类型(byte、short、int、long)和浮点类型(fl...

    gzq大数据
  • Java原型模式(prototype)

      prototype模式也就是原型模式,是javaGOF23种设计模式中的一种,我们在学习spring的时候在bean标签的学习中碰到过,所以本文来给大家介绍...

    用户4919348
  • 单例设计模式

    喜欢天文的pony站长
  • 第22次文章:建造者模式+原型模式

    这周我们就可以把GOFO23设计模式中的创建型模式全部介绍完了!后面在项目里面可以试一下啦!

    鹏-程-万-里

作者介绍

cMusketeer

山东中驰汽配电子商务有限公司Android开发工程师

山东中驰汽配电子商务有限公司 · Android开发工程师 (已认证)

精选专题

活动推荐

扫码关注云+社区

领取腾讯云代金券