java单列模式详解_java单例模式详解

饿汉法

饿汉法就是在第一次引用该类的时候就创建对象实例,而不管实际是否需要创建。代码如下:

1 public classSingleton {2 private static Singleton = newSingleton();3 privateSingleton() {}4 public staticgetSignleton(){5 returnsingleton;6 }7 }

缺点:无法实现对象延时加载。

懒汉法

懒汉式就是需要使用该类的时候再创建对象实例(进而实现了对象的延时加载,减少了系统负荷)。

1.单线程实现方式,代码如下:

1 public classSingleton {2 private static Singleton singleton = null;3 privateSingleton(){}4 public staticSingleton getSingleton() {5 if(singleton == null) singleton = newSingleton();6 returnsingleton;7 }8 }

缺点:线程不安全,如果有多条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。

2.线程安全方式,代码如下:

1 public classSingleton {2 private static volatile Singleton singleton = null;3 privateSingleton(){}4 public staticSingleton getSingleton(){5 synchronized (Singleton.class){6 if(singleton == null){7 singleton = newSingleton();8 }9 }10 returnsingleton;11 }12 }

说明:使用volatile关键字进行限制,保证其对所有线程的可见性,并且禁止对其进行指令重排序优化。

缺点:每次调用getSingleton()方法,都会因为synchronized关键字进行等待,效率低下。

3.兼顾线程安全和效率方式,代码如下:

public classSingleton {private static volatile Singleton singleton = null;privateSingleton(){}public staticSingleton getSingleton(){if(singleton == null){synchronized (Singleton.class){if(singleton == null){

singleton= newSingleton();

}

}

}returnsingleton;

}

}

说明:“双重检查锁”,使用双判断null方式,可以减少线程进行等待,提高效率。

扩展:

方式2中说明:

1.可见性:指的是在一个线程中对该变量的修改会马上由工作内存(Work Memory)写回主内存(Main Memory),所以会马上反应在其它线程的读取操作中。(工作内存是线程独享的,主存是线程共享的);

2.重新排序:禁止指令重排序优化。我们写的代码(尤其是多线程代码),由于编译器优化,在实际执行的时候可能与我们编写的顺序不同。编译器只保证程序执行结果与源代码相同,却不保证实际指令的顺序与源代码相同。这在单线程看起来没什么问题,然而一旦引入多线程,这种乱序就可能导致严重问题。volatile关键字就可以从语义上解决这个问题。(但是禁止指令重排优化这条语义直到jdk1.5以后才能正确工作。此前的JDK中即使将变量声明为volatile也无法完全避免重排序所导致的问题。所以,在jdk1.5版本前,双重检查锁形式的单例模式是无法保证线程安全的。)

静态内部类法

1 public classSingleton {2 private static classHolder {3 private static Singleton singleton = newSingleton();4 }5 privateSingleton(){}6 public staticSingleton getSingleton(){7 returnHolder.singleton;8 }9 }

优点:静态内部类只有在使用的时候才会被加载,不会随主类的加载而加载,实现了延时加载,静态内部类只会被加载一次,保证了线程安全。

枚举写法

1 public enumSingleton {2 INSTANCE;3 privateString name;4 publicString getName(){5 returnname;6 }7 public voidsetName(String name){8 this.name =name;9 }10 }

优点:防止用户使用反射方式调用私有构造器;提供了自动序列化机制,防止反序列化的时候创建新的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值