标签:
在Java这这门语言里面,它的优点在于它本身的可移植性上面,而要做到可移植的话,本身就需要一个中介作为翻译工作,以达到本地和Java的统一,但是就这点而言就相当的消耗资源,所以就Java程序员需要不断的去优化自己的代码。今天所研究的单例模式就是在这样的条件下产生的,
所谓单例模式,就是只有一个实例,在堆里面只有一个。假如我们的实例,就需要一个,但是会多次用到,这样的话就会出现很尴尬的问题。
比如:
在上述里面我们了解到,单例模式在我们项目中,几乎是天天出现,所以在这里,我们仔细研究一下,这种设计模式的怎么实现最好(说到实现,它的实现我们大多数人只知道有两种,而还有三种模式知道的人不是很多,以及利用反序列化,反射漏洞去强制解除单例)
1 public class Eager_Singleton {
2
3 private static Eager_Singleton singleton = new Eager_Singleton();
4
5 private Eager_Singleton(){}
6
7 public static Eager_Singleton newInstance(){
8 return singleton;
9 }
10 }
/**
* 懒汉单例模式
* @author 刘酸酸
*
*/
public class Sluggard_Singleton {
private static Sluggard_Singleton singleton = null;
private Sluggard_Singleton(){}
public synchronized static Sluggard_Singleton newInstance(){
if(singleton == null){
singleton = new Sluggard_Singleton();
}
return singleton;
}
}
/**
* 双重检查锁实现单例模式
* @author 刘酸酸
*
*/
public class DoubleCheck_Singleton {
private static DoubleCheck_Singleton instance = null;
public static DoubleCheck_Singleton getInstance() {
if (instance == null) {
DoubleCheck_Singleton sc;
synchronized (DoubleCheck_Singleton .class) {
sc = instance;
if (sc == null) {
synchronized (DoubleCheck_Singleton .class) {
if(sc == null) {
sc = new DoubleCheck_Singleton ();
}
}
instance = sc;
}
}
}
return instance;
}
private DoubleCheck_Singleton () {
}
}
静态内部类方式实现
/**
* 测试静态内部类实现单例模式
* 这种方式:线程安全,调用效率高,并且实现了延时加载!
* @author 刘酸酸
*
*/
public class StaticInnerClass{
private static class StaticInnerClass{
private static final StaticInnerClass instance = new StaticInnerClass();
}
private StaticInnerClass(){
}
//方法没有同步,调用效率高!
public static StaticInnerClassgetInstance(){
return StaticInnerClass.instance;
}
}
比如使用反序列化,和使用反射是不能打破这个原则的
优点:上诉
缺点:不能延迟加载
/**
* 测试枚举式实现单例模式(没有延时加载)
* @author 刘酸酸
*
*/
public enum Enum_Singleton{
//这个枚举元素,本身就是单例对象!
INSTANCE;
//添加自己需要的操作!
public void xxxxx(){
}
}
import java.lang.reflect.Constructor;
/**
* 测试反射和反序列化破解单例模式
* @author 刘酸酸
*
*/
public class Main{
public static void main(String[] args) throws Exception {
//通过反射的方式直接调用私有构造器
Class<Singleton> clazz = (Class<Singleton>) Class.forName("com.suansuan.singleton.Singleton");
Constructor<Singleton> c = clazz.getDeclaredConstructor(null);
//跳过合法检查
c.setAccessible(true);
Singleton s1 = c.newInstance();
Singleton s2 = c.newInstance();
System.out.println(s1);
System.out.println(s2);
}
}
/**
* 测试懒汉式单例模式(如何防止反射和反序列化漏洞)
* @author 刘酸酸
*
*/
public class Singleton implements Serializable {
//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。
private static Singleton instance;
private Singleton (){ //私有化构造器
//反射时,我们作如下操作既可以规避,跳过合法检测的非法访问
if(instance!=null){
throw new RuntimeException();
}
}
//方法同步,调用效率低!
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton ();
}
return instance;
}
//反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!
private Object readResolve() throws ObjectStreamException {
return instance;
}
}
总结:使用枚举去替代饿汉式,使用静态内部类去替代懒汉式
标签:
原文地址:http://www.cnblogs.com/dry0515/p/5817828.html