设计模式
来源:互联网 发布:专升本c语言考试大纲 编辑:程序博客网 时间:2024/05/21 10:51
设计模式之单利
单利设计模式是非常常用的一种设计模式,也是提高效率的一种设计思路。单利其实还是很发杂的。
很多朋友其实早就接触了单利只是没有留意而已, Servlet 就是一个单实例多线程的,所以Servlet存在线程安全
问题! 今天和大家分享一下单利的原理。
一.饿汉式单利
现在很多程序员不关心JAVA的内存分配,以为JVM都可以搞定那么这是错误的。如果你对内存分配不是很在行还是要
了解一下,单利和内存分配,多线程是密不可分的。 饿汉式是比较简单, 看代码。
/*饿汉式单利设计模式*/class Singleten_ehanshi{private static Singleten_ehanshi s = new Singleten_ehanshi();private Singleten_ehanshi(){}public static Singleten_ehanshi getInstance(){return s;}}
为什么说单利可以提高效率但有线程安全问题?
当JVM通过类加载器加载类的时候Static并没有分配在堆内存上,而是在静态区(这是还没有类实例加载)。
这样保证了一个实例在内存中不会有多余的实例分配在堆内存中,所以效率会高一些。既然是Static的实例那么所有线程过来
多可以修改公共的东西(成员)所以安全性有问题,这和Servlet一样的问题。
二.懒汉式单利
/*单利设计模式: 懒汉式。多线程的问题解决.*/class Singleten_lanhanshi{private static Singleten_lanhanshi sgl = null;private Singleten_lanhanshi(){}public static Singleten_lanhanshi getInstace(){if(sgl == null) //减少锁的判断次数.{//这时候同步使用的是 字节码这个锁synchronized(Singleten_lanhanshi.class){if(sgl == null){sgl = new Singleten_lanhanshi();}}}return sgl;}public static void main(String[] args) {System.out.println("Hello World!");}}
大家可能对程序中为什么加一把锁而疑惑,这是懒汉式中比较重要的东西,多线程的问题就是由此而引起的。
我们来解释下这段代码
if(sgl == null) //减少锁的判断次数.{//这时候同步使用的是 字节码这个锁synchronized(Singleten_lanhanshi.class){if(sgl == null){sgl = new Singleten_lanhanshi();}}}
大家对于第一个应该明白,就是为了减少线程对锁的判断次数。
为什么要加一把锁?我们用多线程来推理, 当地一个线程判断了实例为空后可能会成为等待状态(或冻结)如图
第二个线程进来加了一把锁,并且对静态区的对象实例化,注意这时候对象已经不为空了。
这线程一醒了他还停留在对象为空的时候,又去实例化了一次这就出现了错误,所以必须同步。
同步为什么用这样的锁而不是对象锁呢?
这就是内存分配了, 大家想想当类加载的时候Static的先于对象被加载进内存,这个时候内存中还没有任何对象所以对象
锁是不可能的, 但是静态区中有这个静态对象本身所以要用这把锁。
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式~~~~~~~~~~
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- hbase 的regioninfo
- poj 2406
- 很不错的后台界面收集[提供下载]
- 理解游标(2)游标的属性介绍及不同游标类别的案例演示
- Win8风格的Web启动界面
- 设计模式
- 为什么需要编译安装x86和arm版的qt-embedded
- Image is not displaying proper using OpenGL in android ndk
- 多维数据集的主动缓存(Proactive Caching)
- 这几天胃口不错。
- awk 知识点
- [leetcode] Best Time to Buy and Sell Stock
- 要总结掌握的知识
- Redis Primer(1)基于JedisPool的Redis hset并发性能测试