单例模式(Singleton Pattern):

在平时的开发中,可能会用到单例模式,许多java的笔试题中也会叫笔试者写出单例模式的那几种写法并且分析。那么下面就来轻轻地探讨一下,最简单的设计模式,即单例模式。

单例模式的解释:

GoF对单例模式的定义:保证一个类只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。说的意思就是一个类在整个程序中就只能有一个实例,并且这个类中要定义一些可以全局访问的属性、方法等。

单例模式的要点有三:

1、有且仅有一个实例。 2、自己创建自己的实例。 3、自己向整个应用程序提供这个实例。

单例模式的应用场景:

如窗口管理系统、打印缓冲池、文件系统它们都是原型的例子。

单例模式按实例化对象的时间先后可以大体分为两种类型,即饿汉式和懒汉式,接下来将列出5种单例模式的写法,并分析他们缺点。

第一种:饿汉式

/**
* 单例模式-饿汉式
*/
public class Singleton
{
// 在定义的时候就初始化_instance,
private static Singleton _instance = new Singleton(); // 够造函数必须是私有的,不能被外部直接调用。
private Singleton()
{
} // 暴露给外部,提供实例。
public static Singleton getInstance()
{
return _instance;
}
}

缺点:在加载类的时候就实例化了对象,比较浪费资源。

第二种:懒汉式

/**
* 单例模式-懒汉式(一)
*/
public class Singleton
{
private static Singleton _instance; // 够造函数必须是私有的,不能被外部直接调用。
private Singleton()
{
} // 暴露给外部,提供实例。
public static Singleton getInstance()
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}

缺点:多线程不安全。比如两个线程同时进入getInstance()发现instance为空,那么它们都会去执行new Singleton(),从而导致实例不止一个。

第三种:懒汉式 - 加锁两次判断

/**
* 单例模式-懒汉式(二)
*/
public class Singleton
{
private static Singleton _instance;
private static readonly object synchronized = new object();
// 够造函数必须是私有的,不能被外部直接调用。
private Singleton()
{
} // 暴露给外部,提供实例。
public static Singleton getInstance()
{
if (_instance == null)
{
lock (synchronized) //加锁防止多线程
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}

缺点:对方法进行了同步,解决了多线程访问时的不安全性,但是每次调用getInstance()都会去判断锁的状态,比较耗时。

第四种:懒汉式 - 内部类

/**
* 单例模式-懒汉式(四)
*/
public class Singleton
{
// 够造函数必须是私有的,不能被外部直接调用。
private Singleton()
{
} // 暴露给外部,提供实例。
public static Singleton getInstance()
{
return SingletonHolder._instance;
} // 静态内部内,实现延时加载
private static class SingletonHolder
{
public static Singleton _instance = new Singleton();
}
}

优点:实现了延时加载,也就是说没有在类被加载时就去实例话对象。

下面是黑马老师讲的,懒汉式加锁解决多线程安全问题。

 public class Singleton
{
private static Singleton _instance;
private static readonly object syn = new object();
private Singleton() //构造函数设置private,不能被new,单例模式
{ }
public static Singleton CreateInstance()
{
if (_instance == null)
{
lock (syn) //加锁防止多线程
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}

最新文章

  1. 高级javascript---变量作用域
  2. 用VBox虚拟机安装Android 屏幕90度翻转竖屏设置
  3. 一个人java深入理解java logback配置
  4. NSURLSessionTask使用dispatch_semaphore 完成同步机制
  5. Devexpress Winform Gridcontrol 中根据条件单元格的值改变单元格的颜色等属性。
  6. link与import的区别
  7. osgearth_city例子总结
  8. jsoup: Java HTML Parser (类似jquery)
  9. SSO(单点登录)
  10. Android快捷键
  11. MFC无边框窗体不响应任务栏点击问题
  12. C++ vector的用法
  13. 我最喜欢的visual studio 2013的新特性
  14. codeblocks + MinGW 以及vc 使用预编译头文件的方法
  15. Emmet插件
  16. 一些Android框架
  17. 解决Postman发送post数据但是Node.js中req.body接收不到数据的问题[已解决]
  18. [转]SQL Server 表变量和临时表的区别
  19. SQL Server-聚焦ROW_NUMBER VS TOP N性能
  20. W3CSchool闯关笔记(中级脚本算法)

热门文章

  1. vue 声明响应式属性
  2. ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。
  3. sublime和webstorm安装zencoding
  4. TP中单字母快捷函数总结
  5. phpcms v9 配置sphinx全文索引教程
  6. OpenGL ES andoid学习————2
  7. ubuntu虚拟化平台libvrit-bin
  8. Codeforces 678E Another Sith Tournament 状压DP
  9. 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree
  10. windows下在Eclipse中启动的tomcat没有乱码,单独部署到tomcat下乱码解决方案