
I. 简介
有些我们只需要一个对象,例如线程池,缓存,对话框注册表对象,日志对象等. 实际上,这些类对象只能有一个实例. 如果创建多个实例,将导致很多问题,例如程序异常,资源过度使用或结果不一致.
全局变量可以提供全局访问,但是不能保证只有一个实例. 全局变量还有其他缺点. 全局变量不能延迟加载(也就是说,在声明变量时必须初始化对象). 如果初始化此对象是一项耗时的操作,并且可能永远无法使用,那就很浪费.
让我们看一下经典的单例实现:


注意: 这仅说明了单例实现的三个要素,这在多线程环境中是有问题的,稍后将进行解释和解决.
简单定义:
Singleton模式是确保一个类只有一个实例,并提供一个[b]安全的全局访问点. [/ b]
第二singleton单例模式,处理多线程
单例模式是一种相对容易理解的设计模式,并且具有相对简单的结构和使用. 重点是实施.

以上单例实现方法可能会在多线程中的第3点创建多个实例. 下面有几种解决方案.
1. 最简单的方法是将同步关键字添加到方法声明中以获得单例:
Public static synchronized Singleton getInstance(){…}
此方法很简单singleton单例模式,但是存在问题. 实际上,只有第一个调用才需要这种同步操作,而随后的所有调用都使用同步操作来提高性能,这是严重的浪费.
2. 及时初始化. 第一步是在声明私有静态变量时直接创建对象,而不是延迟初始化. 上面已简要比较了延迟初始化和及时初始化之间的区别.

3. 采用双重检查锁定.

这主要是对第一个解决方案的优化. 请务必注意此处使用键“ volatile”. 没有此关键字编写仍然不安全. 这里的不安全性不是创建两个变量,而是导致对象在完全创建之前被其他线程使用,并使用未完全初始化的对象.
4. 在内部类的帮助下,还有一种使用单例的推荐方法.


5. 使用枚举类型实现单例. 将单例类更改为枚举类型. 只有一个枚举常量,它是它自己的实例,在构造函数中创建. 该方法可以有效解决以下问题: 使用反射来构建多个实例,序列化后的单例创建多个实例,反序列化后的多线程. 缺点是该类的某些特性丢失了.
在我的文章: Java并行编程/“
参考:
“ HeadFirst”
您尚未登录,请先登录,然后再发表评论
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-166530-1.html
爱你一生不后悔
放弃那些陈旧的