设计模式

设计模式之单利

 

        单利设计模式是非常常用的一种设计模式,也是提高效率的一种设计思路。单利其实还是很发杂的。

 

很多朋友其实早就接触了单利只是没有留意而已,  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的先于对象被加载进内存,这个时候内存中还没有任何对象所以对象

锁是不可能的, 但是静态区中有这个静态对象本身所以要用这把锁。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值