java的单例设计模式解读

java中的单例设计模式应用很多,比如Calendar,我们的电脑的任务管理器,回收站都是单例的等等 ,spring的bean 也是默认单例的

     这里用代码来简单说明下

       饿汉式:    

package com.asiainfo.singleton;


/**
 * 饿汉式
 *   缺点,不能延时加载
 * @author zengml
 *
 */
public class SigletonHungry {
	//首先初始化对象,采用static来修饰,是为了线程安全,因为static修饰,只会在jvm中加载一次
	public static SigletonHungry  sigletonHungry = new SigletonHungry();
	
	
	//私有化构造器,防止以new 对象的方式来创建
	private SigletonHungry(){
		
	}
	
	//定义个返回对象的出口
	public static  SigletonHungry getInstance(){
		return sigletonHungry;
	}
   
}

懒汉式:

package com.asiainfo.singleton;

/**
 * 懒汉式
 * @author zengml
 *
 */
public class SigletonLazy {
    //不初始化lazy变量
	public static SigletonLazy lazy;
	
	//私有化构造器,防止以new 对象的方式来创建
	private SigletonLazy(){
		
	}
	
	public static SigletonLazy getInstance(){
		//因为加了同步锁,会导致效率变慢很多,这里也不会常用
		synchronized (SigletonLazy.class) {
			if(lazy==null){
				lazy = new SigletonLazy();
			}
		}
		return lazy;
	}
}
静态内部类单例模式:   
package com.asiainfo.singleton;

/**
 * 静态内部类实现单例模式
 *   实现了延时加载,调用效率也高,个人觉得这种单例比较好
 * @author Administrator
 *
 */
public class SingletonStaticClass {
	
	//静态内部类
	private static class StaticClass{
		private static SingletonStaticClass instance = new SingletonStaticClass();
		
	}
	
	//私有化构造器,防止以new 对象的方式来创建
	private SingletonStaticClass(){
		
	}
	
	//定义个返回对象的出口,当调用StaticClass.instance时候,才会加载对象,这里实现了延时加载,又是线程安全的
	public static  SingletonStaticClass getInstance(){
		return StaticClass.instance;
	}
}

静态内部类方式,结合了饿汉式和懒汉式的有点,面试的时候,面试官一般都会问,哪个效率高,懒汉式怎么保证数据安全等等

还要注意一点,我们的反射和序列化 是可以破解单例模式的

    反射破解:

    

package com.asiainfo.test;

import java.lang.reflect.Constructor;

import com.asiainfo.singleton.SigletonHungry;
import com.asiainfo.singleton.SigletonLazy;
import com.asiainfo.singleton.SingletonStaticClass;

public class TestSingleton {
	public static void main(String[] args) throws Exception {
		//饿汉式
		SigletonHungry SigletonHungry1 = SigletonHungry.getInstance();
		SigletonHungry SigletonHungry2 = SigletonHungry.getInstance();
		System.out.println(SigletonHungry1);
		System.out.println(SigletonHungry2);
		
		
		//懒汉式
		SigletonLazy SigletonLazy1 = SigletonLazy.getInstance();
		SigletonLazy SigletonLazy2 = SigletonLazy.getInstance();
		System.out.println(SigletonLazy1);
		System.out.println(SigletonLazy2);
		
		
		//静态内部类单例
		SingletonStaticClass SingletonStaticClass1 = SingletonStaticClass.getInstance();
		SingletonStaticClass SingletonStaticClass2 = SingletonStaticClass.getInstance();
		System.out.println(SingletonStaticClass1);
		System.out.println(SingletonStaticClass2);
		
		//反射破解
		Class<SigletonHungry> clazz = (Class<SigletonHungry>)Class.forName("com.asiainfo.singleton.SigletonHungry");
		Constructor<SigletonHungry> Constructor = clazz.getDeclaredConstructor();
		//可以访问私有构造器
		Constructor.setAccessible(true);
		
		System.out.println(Constructor.newInstance());
		System.out.println(Constructor.newInstance());
	}
}

结果:  
com.asiainfo.singleton.SigletonHungry@773de2bd
com.asiainfo.singleton.SigletonHungry@773de2bd
com.asiainfo.singleton.SigletonLazy@7700b3c2
com.asiainfo.singleton.SigletonLazy@7700b3c2
com.asiainfo.singleton.SingletonStaticClass@60b07af1
com.asiainfo.singleton.SingletonStaticClass@60b07af1
com.asiainfo.singleton.SigletonHungry@625795ce
com.asiainfo.singleton.SigletonHungry@642c39d2



  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值