首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

怎么实现Singleton模式才是高效和安全的

2012-09-21 
怎样实现Singleton模式才是高效和安全的?关于Singleton的实现方式,有如下多种方式,究竟那一种是高效安全的

怎样实现Singleton模式才是高效和安全的?

关于Singleton的实现方式,有如下多种方式,究竟那一种是高效安全的呢??

1、大家熟知的懒式单例

public class LazySingleton {

?private static LazySingleton instance = null;

?private static boolean flag = true;

?private LazySingleton() {
?}

?public static LazySingleton getInstance() {
??if (instance == null) {
???letMeSleep() ;
???instance = new LazySingleton();
??}
??System.out.println("instance.hashCode() : " + instance.hashCode());
??return instance;
?}

?private static void letMeSleep() {
??if (true) {
???try {
????System.out.println("let me sleep 3 sec.!");
????Thread.currentThread().sleep(3000);
????System.out.println("waking up.");
???} catch (InterruptedException e) {
????e.printStackTrace();
???}
??}
?}


?public static void main(String[] agrs) {

? //实例化两个线程
??new Thread(new Runnable() {
???public void run() {
????LazySingleton s = LazySingleton.getInstance();
???}
??}).start();
??new Thread(new Runnable() {
???public void run() {
????LazySingleton s = LazySingleton.getInstance();
???}
??}).start();
?}

}

执行结果分析:

let me sleep?3 sec.!
let me sleep?3 sec.!
waking up.
instance.hashCode() : 6413875
waking up.
instance.hashCode() : 21174459

每个线程获取的实例不一样。

?

2、好吧,用同步synchronized

???? 有人是这样实现的:

public static LazySingleton getInstance() {?
??????? if (null == instance) {
??????????? synchronized (LazySingleton .class) {???????
??????????????????instance = new LazySingleton ();?
??????????? }
??????? }?
??????? return instance;
??? }

这样是否正确呢,我们还用上面的思路来进行测试:

let me sleep 3 sec.!
let me sleep 3 sec.!
waking up.
instance.hashCode() : 21174459
waking up.
instance.hashCode() : 827574

结果很不幸:(。原因在于在两个线程都执行到了if (null == instance)? 里面的逻辑,然后依次执行????instance = new LazySingleton ();?这样获取两个instance实例就是正常的了。到了这里,大家都肯定知道在执行 instance = new LazySingleton () 还要判断下instance是否为空。同步块影响性能吧?想必答案是肯定的。

3、简单,安全的写法:

???

public class Singleton {

?private static Singleton instance = new Singleton();

?private Singleton() {
?}

?public static Singleton getInstance() {
??letMeSleep() ;
??System.out.println("instance.hashCode() : " + instance.hashCode());
??return instance;
?}

这样的写法简单,也安全。但是考虑到构造函数里面加载很多东西,势必延长初始化时间。

4、利用静态内部类提前实例化

public class HolderSingleton {

?private HolderSingleton(){
?}
?
?public static class SingletonHolder{
??private static HolderSingleton instance = new HolderSingleton() ;
?}
?
?public static HolderSingleton getInstance(){
??letMeSleep();
??System.out.println(SingletonHolder.instance.getClass().hashCode()) ;
??return SingletonHolder.instance ;
?}
?private static void letMeSleep() {
??if (true) {
???try {
????System.out.println("let me sleep 3 sec.!");
????Thread.currentThread().sleep(3000);
????System.out.println("waking up.");
???} catch (InterruptedException e) {
????e.printStackTrace();
???}
??}
?}
?这个在JVM这一个层次有第三中山实现方式有何不一样?

热点排行