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