java 单例模式的实例详解

概念:

java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。

单例模式有一下特点:

1、单例类只能有一个实例。

2、单例类必须自己自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

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

首先看一个经典的单例实现。

public class Singleton {

private static Singleton uniqueInstance = null;

private Singleton() {

// Exists only to defeat instantiation.

}

public static Singleton getInstance() {

if (uniqueInstance == null) {

uniqueInstance = new Singleton();

}

return uniqueInstance;

}

// Other methods...

}

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)

但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。

public class TestStream {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

//该类只能有一个实例

private TestStream(){} //私有无参构造方法

//该类必须自行创建

//有2种方式

/*private static final TestStream ts=new TestStream();*/

private static TestStream ts1=null;

//这个类必须自动向整个系统提供这个实例对象

public static TestStream getTest(){

if(ts1==null){

ts1=new TestStream();

}

return ts1;

}

public void getInfo(){

System.out.println("output message "+name);

}

}

/**

*

*/

public class TestMain {

public static void main(String [] args){

TestStream s=TestStream.getTest();

s.setName("张孝祥");

System.out.println(s.getName());

TestStream s1=TestStream.getTest();

s1.setName("张孝祥");

System.out.println(s1.getName());

s.getInfo();

s1.getInfo();

if(s==s1){

System.out.println("创建的是同一个实例");

}else if(s!=s1){

System.out.println("创建的不是同一个实例");

}else{

System.out.println("application error");

}

}

}

运行结果:

张孝祥

张孝祥

output message 张孝祥

output message 张孝祥

创建的是同一个实例

结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。

1.饿汉式单例类

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

public class Singleton1 {

//私有的默认构造子

private Singleton1() {}

//已经自行实例化

private static final Singleton1 single = new Singleton1();

//静态工厂方法

public static Singleton1 getInstance() {

return single;

}

}

2.懒汉式单例类

//懒汉式单例类.在第一次调用的时候实例化

public class Singleton2 {

//私有的默认构造子

private Singleton2() {}

//注意,这里没有final

private static Singleton2 single=null;

//静态工厂方法

public synchronized static Singleton2 getInstance() {

if (single == null) {

single = new Singleton2();

}

return single;

}

}

3.登记式单例类

import java.util.HashMap;

import java.util.Map;

//登记式单例类.

//类似Spring里面的方法,将类名注册,下次从里面直接获取。

public class Singleton3 {

private static Map map = new HashMap();

static{

Singleton3 single = new Singleton3();

map.put(single.getClass().getName(), single);

}

//保护的默认构造子

protected Singleton3(){}

//静态工厂方法,返还此类惟一的实例

public static Singleton3 getInstance(String name) {

if(name == null) {

name = Singleton3.class.getName();

System.out.println("name == null"+"--->name="+name);

}

if(map.get(name) == null) {

try {

map.put(name, (Singleton3) 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) {

Singleton3 single3 = Singleton3.getInstance(null);

System.out.println(single3.about());

}

}

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

java单例模式 实例_java 单例模式的实例详解相关推荐

  1. java jtable组件_java中jtable组件详解实例

    java中jtable组件详解实例 java 表格控件 JTable 常用操作详解 JTable 是 Swing 编程中很常用的控件,这里总结了一些常用方法以备查阅.欢迎补充,转载请注明作者与出处.一 ...

  2. java file 实例_Java File类的详解及简单实例

    Java File类的详解及简单实例 1. File():构造函数,一般是依据文件所在的指定位置来创建文件对象. CanWrite():返回文件是否可写. CanRead():返回文件是否可读. Co ...

  3. 异常将上下文初始化事件发送到类的侦听器实例._Java CLassLoader类加载器详解,一点课堂(多岸学院)...

    Java CLassLoader 类加载器(class loader)是 Java™中的一个很重要的概念.类加载器负责加载 Java 类的字节代码到 Java 虚拟机中.本文首先详细介绍了 Java ...

  4. java list用法_java list的用法详解

    java list的用法详解 java中可变数组的原理就是不断的创建新的数组,将原数组加到新的数组中.以下是百分网小编搜索整理的关于java list的用法详解,需要的朋友可以参考一下!想了解更多相关 ...

  5. java aqs原理_Java并发之AQS详解

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronized(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  6. java 枚举 方法_Java枚举使用方法详解

    在实际编程中,往往存在着这样的"数据集",它们的数值在程序中是稳定的,而且"数据集"中的元素是有限的. 例如星期一到星期日七个数据元素组成了一周的"数 ...

  7. java 返回值_Java方法返回值详解

    Java方法返回值详解 每个方法都是为了完成某个特定的功能,例如:登录功能.求和功能等,既然是功能,那么当这个功能完成之后,大多数情况下都会有一个结果的,比如,登录成功了或者失败了(true/fals ...

  8. java子类继承父类实例_Java子类继承父类详解

    别和我说你真的懂了继承,先来看下面的代码,回答出我的问题再说 代码很简单,如下: 父类: public class T { public void run() { System.out.println ...

  9. java中组合_java中组合模式详解和使用方法

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...

  10. java自定义线程_Java自定义线程池详解

    自定义线程池的核心:ThreadPoolExecutor 为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制,其中在java.util.concurrent ...

最新文章

  1. |DataDirectory|的使用
  2. 打印机尚未链接到此计算机,win10系统无法连接打印机显示未指定设备的解决方法...
  3. abaqus python二次开发攻略_Abaqus有限元分析常见问题解答与实用技巧 12天后上架...
  4. Qt Creator将QML模块与插件一起使用
  5. 深度学习:网络的编程模式比较
  6. 战双帕弥什自抽号怎么使用_战双帕弥什新S冰露怎么玩《战双帕弥什》新S冰露玩法技巧...
  7. 鸿蒙os智能座舱,华为智能座舱的野心:HiCar上车,为鸿蒙OS铺路
  8. Spring Boot基础学习笔记09:Thymeleaf模板引擎
  9. 68 个人脸landmark 点分布图
  10. From Apprentice To Artisan 翻译 17
  11. PySpark︱DataFrame操作指南:增/删/改/查/合并/统计与数据处理
  12. 如何解决PS软件工作区不能吸附到工具栏?
  13. [转载]软件测试学习资料
  14. JS 字符串变量全局替换
  15. 计算机毕业设计的步骤
  16. python print end参数_python print的参数详解
  17. [Oracle] 自定义数据类型Type
  18. 作为 Gopher, 你知道 Go 的注释即文档应该怎么写吗
  19. php小数点后保留一位或两位小数
  20. 小科普:什么是屏幕分辨率

热门文章

  1. python 逻辑回归_不会Python没问题!用Excel实现简单的逻辑回归!
  2. OpenCV-图像处理(33、基于距离变换与分水岭的图像分割)
  3. ubuntu 下codeblocks的相关配置
  4. 【Wannafly挑战赛14 E】无效位置(并查集思想+线性基合并)
  5. 【浙大第19届校赛:B】Even Number Theory (数论n!中有多少个质因子2+java大数)
  6. 关于如何理解链表结构体指针引用LinkNode * L的问题
  7. java nio 下载网页_JavaNIO 下载网络文件保存本地报java.nio.file.AccessDeniedException:无权限操作...
  8. 如何让sublime编译c语言,如何在Sublime Text 3中编译C程序?
  9. linux 内核logo 居中,linux logo制作及居中显示
  10. 价值连城 神经网络- 吴恩达Andrew Ng Coursera Neural Networks and Deep Learning