Java单例模式简单介绍

一、概念

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。就笔者认为,单例就是不让外界创建对象。

1.1概念剖析

对于单例的话,从上面的概念剖析,应该满足下面的几个条件:

第一:单例类中只能有一个单例对象;

第二:单例类必须自己创建自己的唯一实例对象;

第三:这个实例对象能够给外界访问到,并且外界不能够自己创建对象。

二、常见几种单例模式的方式

在java中,对于单例模式一般来说,分为懒汉式,饿汉式,以及登记式,但是登记式一般较少看到,所以也容易忽略。笔者若非今天突然想总结一下,在网上查找资料,也不会注意到这个。下面按照这种方式来贴出代码,并进行解释。

2.1饿汉式单例类

package com.ygh.singleton;
/**
 * 饿汉式单例类
 * @author 夜孤寒
 * @version 1.1.1
 */
public class HungerSingleton {
  //将构造方法私有,外界类不能使用构造方法new对象
  private HungerSingleton(){}
  //创建一个对象
  private static final HungerSingleton lazySinleton=new HungerSingleton();
  //设置实例获取方法,返回实例给调用者
  public static HungerSingleton getInstance(){
    return lazySinleton;
  }
}

写一个测试类,测试是不是实现单例:

package com.ygh.singleton;
/**
 * 测试单例类
 *
 * @author 夜孤寒
 * @version 1.1.1
 */
public class Test {
  public static void main(String[] args) {
    /*
     * 构造方法私有化,不能够使用下面方式new对象
     */
    //HungerSingleton hungerSingleton=new HungerSingleton();
    //使用实例获取方法来获取对象
    HungerSingleton h1=HungerSingleton.getInstance();
    HungerSingleton h2=HungerSingleton.getInstance();
    System.out.println(h1==h2);//true
  }
}

从上面可以看出:这个测试类的两个引用是相等的,也就是说两个引用指向的是同一个对象,而这也正好符合单例模式标准。到这里,饿汉式介绍结束。

2.2饿汉式单例类

package com.ygh.singleton;
/**
 * 懒汉式单例类
 * @author 夜孤寒
 * @version 1.1.1
 */
public class LazySingleton {
  //将构造方法私有,外界类不能使用构造方法new对象
  private LazySingleton(){}
  //创建一个对象,不为final
  private static LazySingleton lazySingleton=null;
  //设置实例获取方法,返回实例给调用者
  public static LazySingleton getInstance(){
    //当单例对象不存在,创建
    if(lazySingleton==null){
      lazySingleton=new LazySingleton();
    }
    //返回
    return lazySingleton;
  }
}

测试类:

package com.ygh.singleton;
/**
 * 测试单例类
 *
 * @author 夜孤寒
 * @version 1.1.1
 */
public class Test {
  public static void main(String[] args) {
    /*
     * 构造方法私有化,不能够使用下面方式new对象
     */
    //LazySingleton lazySingleton=new LazySingleton();
    //使用实例获取方法来获取对象
    LazySingleton l1=LazySingleton.getInstance();
    LazySingleton l2=LazySingleton.getInstance();
    System.out.println(l1==l2);//true
  }
}

从上面可以看出:这个测试类的两个引用是相等的,也就是说两个引用指向的是同一个对象,而这也正好符合单例模式标准。到这里,懒汉式介绍结束。

2.3懒汉式和饿汉式的区别

懒汉式是当没有对象的时候,就会创建一个单例对象,当有对象的时候,就不会再创建对象,这个说起来可能不是那么容易理解,但是读者如果有兴趣了解更深,可以在eclipse中使用断点来测试,将LazySingleton类的if花括号内的内容加上断点,然后在Test类中,使用debug运行,这样子就能够很容易体现出来,第一次创建了一个对象,但是第二次没有创建对象。

饿汉式则是实现就用final这个关键字将对象创建好了,当调用者需要实例对象的时候,就可以通过getInstance这个方法获取创建好的实例。

2.4登记式单例类

对于登记式单例类,笔者也不是很熟悉,贴了一段网络上的代码以供自己学习参考,请读者自行学习。

import java.util.HashMap;
import java.util.Map;

/**
 * 登记式单例类
 * @author Administrator
 *
 */
public class RegisterSingleton {
 private static Map<String, RegisterSingleton> map = new HashMap<String, RegisterSingleton>();
 static {
  RegisterSingleton single = new RegisterSingleton();
  map.put(single.getClass().getName(), single);
 }

 /*
  * 保护的默认构造方法
  */
 protected RegisterSingleton() {
 }

 /*
  * 静态工厂方法,返还此类惟一的实例
  */
 public static RegisterSingleton getInstance(String name) {
  if (name == null) {
   name = RegisterSingleton.class.getName();
   System.out.println("name == null" + "--->name=" + name);
  }
  if (map.get(name) == null) {
   try {
    map.put(name, (RegisterSingleton) Class.forName(name).newInstance());
   } catch (InstantiationException e) {
    e.printStackTrace();
   } catch (IllegalAccessException e) {
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   }
  }
  return map.get(name);
 }

 /*
  * 一个示意性的商业方法
  */
 public String about() {
  return "Hello, I am RegSingleton.";
 }

 public static void main(String[] args) {
  RegisterSingleton single3 = RegisterSingleton.getInstance(null);
  System.out.println(single3.about());
 }
}

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

(0)

相关推荐

  • 详解java 单例模式及方法总结

    java设计模式--单例模式  单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 核心知识点如下: (1) 将采用单例设计模式的类的构造方法私有化(采用private修饰). (2) 在其内部产生该类的实例化对象,并将其封装成private static类型. (3) 定义一个静态方法返回该类的实例. /** * 方法一 * 单例模式的实现:饿汉式,线程安全 但效率比较低 */ pu

  • java设计模式之单例模式解析

    单例模式是最简单但同时也是很重要的一种设计模式,优点有以下几个方面: 1.当内存占用特别大的类需要频繁地创建销毁时,单例模式可以节省内存和提高性能,例如myBatis里面的sessionFactory 2.当需要对文件做单一读写时,例如同一时间只能同时写入一个windows文本文件,则需要用单例来避免多重读写 缺点是: 1.单例模式没有接口,很难对其进行拓展. 2.不利于测试,没办法直接根据接口mock出一个对象出来测试 最后说下其实现方式主要有饿汉模式和懒汉模式.其中懒汉模式又可以细分为几种,

  • JAVA多线程并发下的单例模式应用

    单例模式应该是设计模式中比较简单的一个,也是非常常见的,但是在多线程并发的环境下使用却是不那么简单了,今天给大家分享一个我在开发过程中遇到的单例模式的应用. 首先我们先来看一下单例模式的定义: 一个类有且仅有一个实例,并且自行实例化向整个系统提供. 单例模式的要素: 1.私有的静态的实例对象 2.私有的构造函数(保证在该类外部,无法通过new的方式来创建对象实例) 3.公有的.静态的.访问该实例对象的方法 单例模式分为懒汉形和饿汉式 懒汉式: 应用刚启动的时候,并不创建实例,当外部调用该类的实例

  • java 单例模式(饿汉模式与懒汉模式)

    java 单例模式 饿汉式单例 对于饿汉模式,我们可这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象. 懒汉式单例类 对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的时候才会行动,从来不知道及早做好准备.它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回. 单例设计模式常用于JDBC链接数据库 注意: 1 我们常用的是第一种饿汉式,因为: (1)既然采用了单例设计模式,就是为了使用单例类的对象

  • Java单例模式实现静态内部类方法示例

    Singleton是众多设计模式中最容易理解的一种,也是众多设计模式中较为重要的一种设计模式.接下来我们看看具体介绍. Singleton模式实现的重点在于将构造函数私有化(private),并通过提供静态公有函数(public synchronized static xxx getInstance)来获取定义在类中的静态私有成员(private static xxx instance),通过一个简单的判断静态实例是否为空来控制这个类只能够new一次,即控制了一个类只能有单个实例,一般的实现如下

  • java设计模式之单例模式的详解及优点

    java设计模式之单例模式 定义:如果一个类始终只能创建一个实例,那么这个类被称为单例类,这种设计模式被称为单例模式. Spring框架里面可以将所有生成的bean对象都设置为单例模式,只需要在配置Bean实例时指定scope="singleton"即可,或者不做配置默认即为单例模式. 我们可以创建一个小的Demo来演示单例模式的实现,只需要保证该类只能创建一个实例,我们可以用权限修饰符private修饰该类的构造器. 提供一个创建该类的接口,该接口只能用static修饰,类里面创建一

  • JAVA 枚举单例模式及源码分析的实例详解

    JAVA 枚举单例模式及源码分析的实例详解 单例模式的实现有很多种,网上也分析了如今实现单利模式最好用枚举,好处不外乎三点: 1.线程安全 2.不会因为序列化而产生新实例 3.防止反射攻击但是貌似没有一篇文章解释ENUM单例如何实现了上述三点,请高手解释一下这三点: 关于第一点线程安全,从反编译后的类源码中可以看出也是通过类加载机制保证的,应该是这样吧(解决) 关于第二点序列化问题,有一篇文章说枚举类自己实现了readResolve()方法,所以抗序列化,这个方法是当前类自己实现的(解决) 关于

  • java 单例模式和工厂模式实例详解

    单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例. 私有的构造方法 指向自己实例的私有静态引用 以自己实例为返回值的静态的公有的方法 饿汉式单例 public class Singleton { private static Singleton singleton = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return singleton; } } 懒

  • java 单例模式的实例详解

    java 单例模式的实例详解 概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打

  • Java单例模式简单介绍

    一.概念 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案.就笔者认为,单例就是不让外界创建对象. 1.1概念剖析 对于单例的话,从上面的概念剖析,应该满足下面的几个条件: 第一:单例类中只能有一个单例对象: 第二:单例类必须自己创建自己的唯一实例对象: 第三:这个实例对象能够给外界访问到,

  • Java单例模式简单示例

    本文实例讲述了Java单例模式.分享给大家供大家参考,具体如下: 在实际开发的时候会有一些需求,在某个类中只能允许同时存在一个对象.这时就需要用到单例模式.代码如下 package org.aaa; public class ex { private static ex e; public static ex getEx() { if (e == null) { e=new ex(); } return e; } private ex() { System.out.println("执行单立模式

  • 简单介绍Java垃圾回收机制

    Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Java深受大家欢迎的众多特性之一,能够帮助程序员更好地编写Java程序. 这篇教程是系列第一部分.首先会解释基本的术语,比如JDK.JVM.JRE和HotSpotVM.接着会介绍JVM结构和Java堆内存结构.理解这些基础对于理解后面的垃圾回收知识很重要. Java关键术语 JavaAPI:一系列帮助开发者创建Java应用程序的封装好的库. Java开发工具包(JDK):一

  • 简单介绍java中equals以及==的用法

    简单介绍 equals方法是java.lang.Object类的方法有两种用法说明: 一.对于字符串变量来说,使用"=="和"equals()"方法比较字符串时,其比较方法不同. 1."=="比较两个变量本身的值,即两个对象在内存中的首地址.(java中,对象的首地址是它在内存中存放的起始地址,它后面的地址是用来存放它所包含的各个属性的地址,所以内存中会用多个内存块来存放对象的各个参数,而通过这个首地址就可以找到该对象,进而可以找到该对象的各个属

  • Java HashSet(散列集),HashMap(散列映射)的简单介绍

    简介 本篇将简单讲解Java集合框架中的HashSet与HashMap. 散列集(HashSet) 快速入门 底层原理:动态数组加单向链表或红黑树.JDK 1.8之后,当链表长度超过阈值8时,链表将转换为红黑树. 查阅HashSet的源码,可以看到HashSet的底层是HashMap,HashSet相当于只用了HashMap键Key的部分,当需要进行添加元素操作时,其值Value始终为常量PRESENT = new Object().以下为HashSet的代码片段: private transi

  • Java基础之简单介绍一下Maven

    一.Maven是什么? Maven是一个跨平台的项目管理工具.作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理,是一个自动化构建工具.maven是Apache的顶级项目,解释为"专家,内行",它是一个项目管理的工具,maven自身是纯java开发的( Theresult is a tool that can now be used for building and managing any Java-basedproject)

  • Java框架入门之简单介绍SpringBoot框架

    前言 Spring都包含了哪些部分呢? 主要包含Spring Boot.Spring Framework.Spring Data.Spring Cloud.Spring Cloud Data Flow.Spring Security.Spring Batch等众多项目.在spring的官网中对其有详细的介绍. 一.SpringBoot是什么? SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,

  • Java中&和&&的区别简单介绍

    & 按位运算符,逻辑运算符 && 逻辑运算符 相同点:只要有一端为假,则语句不成立 假设有三个参数 int x = 1; int y = 2; int q = 1; 作为逻辑运算符时,&左右两端条件式有一个为假就会不成立,但是两端都会运行 if((x+y)==4 & q++>0) {} System.out.println(q); //q=2 &&也叫做短路运算符,因为只要左端条件式为假直接不成立,不会去判断右端条件式. if((x+y)==4

  • Java中Range函数的简单介绍

    目录 前言 Range语法 IntStream范围的语法 LongStream范围的语法 Range函数在Java中是如何工作的? Java中的Range示例 前言 在Java中,Range方法在IntStream和LongStream类中都可用.在IntStream类中,它有助于返回函数参数范围内IntStream的顺序值.在该方法中,startInclusive(inclusive)和endExclusive(exclusive)是与增量步长一起使用的两个参数,如前所述,将包括起始值,并排除

  • Java动态代理简单介绍

    目录 1.代理模式 2.静态代理实现 3.动态代理实现 1.代理模式 当我们需要调用某个类(具体实现类)的方法时,不直接创建该类的对象,而是拿到该类的代理类对象,通过代理对象,调用具体实现类的功能.具体实现类和代理类都实现同样的接口,并且代理类持有实现类的对象.这样做在调用端和具体实现端,做了一层隔离,避免直接打交道. 代理模式在现实中也有很多类似的例子,比如我们买房租房,都得通过中介,这个中介就相当于代理. 2.静态代理实现 1)定义接口: public interface IHouse {

随机推荐