关于多线程下的单例模式及其优化

首先来分析如下单例模式所存在的问题

饿汉式单例模式

测试代码:

public class synDemo01 {
			static Jvm j1=null;
			static Jvm j2=null;
		public static void main(String[] args) {
				
			Thread t1=new Thread("thread1"){
				public void run() {
					j1=Jvm.getJvm(600);
					System.out.println(j1);
				};
			};
			Thread t2=new Thread("thread2"){
				public void run() {
					j2=Jvm.getJvm(500);
					System.out.println(j2);
				};
			};
			t1.start();
			t2.start();
		}
		
}

单例JVM

class Jvm{
	private static Jvm instance=null;
	private Jvm()
	{
		
	}
	
	public static Jvm getJvm(int time)
	{
		if(instance==null)
			{
				try {
					Thread.sleep(time);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				instance=new Jvm();
			}
		return instance;
	}
}

测试结果

com.txr.thread.Jvm@263c8db9
com.txr.thread.Jvm@517c804b
我们发现在多线程之下,竟然实例化了俩个对象

对代码加以改进

单例JVM

class Jvm{
	private static Jvm instance=null;
	private Jvm()
	{
		
	}
	
	public static Jvm getJvm(int time)
	{
		//效率不高,不管任何时候都需要等待,存在对象也需要等待
		synchronized (Jvm.class) {
			if(instance==null)
			{
				try {
					Thread.sleep(time);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				instance=new Jvm();
			}
		}
		return instance;
	}
}

测试结果

com.txr.thread.Jvm@517c804b
com.txr.thread.Jvm@517c804b

发现多线程下的单例是实现了,但是效率却不高,进行如下改进


class Jvm{
	private static Jvm instance=null;
	private Jvm()
	{
		
	}
	
	public static Jvm getJvm(int time)
	{
		//提高效率相当于只锁定了判断
		if(instance==null)
		{
			synchronized (Jvm.class) {//锁定字节码信息
				if(instance==null)
				{
					try {
						Thread.sleep(time);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					instance=new Jvm();
				}
			}
		}
		return instance;
	}
}

测试结果

com.txr.thread.Jvm@517c804b
com.txr.thread.Jvm@517c804b
发现效率提高(从等待时间来看)因为在第一个多线程下的单例模式中,每一个对象进行判断都需要等待,而第二个多线程的单例模式中,当第一个实例化后第二个则无需等待了,这样能大大提高效率


饿汉式的多线程下的单例模式

//饿汉式
	class JVM2{
		private static JVM2 instance=new JVM2();
		private JVM2()
		{
			
		}
		public static JVM2 getJVM3(int time)
		{
			return instance;
		}
	}

很显然在饿汉式的单例模式中不会在多线程的情况下出现问题,因为在类被加载时就已经创建好了实例只需要返回

那么如何进行优化呢?

//饿汉式
	class JVM3{
		//类在使用时才会加载,延缓了加载时间
		private static class JVMholder{
			private static JVM3 instance=new JVM3();
		}
		private JVM3()
		{
			
		}
		public static JVM3 getJVM3(int time)
		{
			return JVMholder.instance;
		}
	}	

将实例化的对象放入内部类中,由类的加载性质我们可以知道这个实例只有在需要的时候才会被创建,这样做的好处就是延缓了加载时间,只有在用到的时候才会被加载.





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值