`
icewubin
  • 浏览: 35027 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

第三种也是最推荐的单例模式

    博客分类:
  • Java
阅读更多
public class Singleton {

    private static class Holder {
        private static final Singleton instance = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return Holder.instance;
    }
}
分享到:
评论
18 楼 icewubin 2012-07-09  
单例的东西一般都是static,或者说单例的逻辑一般都是不需要持久化的,也不需要序列化或者反序列化,没关系的。
17 楼 magicgrass 2012-07-09  
icewubin 写道
pengqb 写道
icewubin 写道
pengqb 写道
Java中我最推荐的单例模式:够简单吧,呵呵
public enum Singleton {
  instance;
}

这种方式是有限制的,你如果enum用得多就知道了,enum有很多限制,毕竟不是普通的类。

还有就是enum的单例的效果是等价于饿汉式初始化方式的,并不是最理想的需要单例时才执行单例初始化代码的模式。

见:Effective java Second Edition 第二章第3条:用私有构造器或枚举类型强化Singleton属性。里面有各种单例模式的详细比较。

你说的我又不是不知道,你怎么这么照本宣读呢?

我不是说了,enum自身有限制的么?例如enum不能继承。

很多时候为了减少类的数量,或者某个单例类中有几个public static的公共方法,或者是有几个public static的常量,此时用我推荐的方式实现单例就是最完美的。

完美的定义:
1.加载这个类的时候不会提引发单例的初始化。

2.即使调用该类的public static方法或public static的常量也不会引提前引发单例的初始化。

3.只有在需要的时候才会初始化单例,而且不需要加同步控制,由JDK自身的classloader机制来完成高效的同步控制,这里的高效是值,只有第一次初始化的时候可能产生竞争,一旦初始化完毕不再产生同步竞争。

enum方式的单例只是符合上述第三条而已。碰到混合型功能的类,或者当前单例需要继承其他类,或者需要有Spring来管理一些有状态的bean的注入的话,enum就不能满足要求了。

如果有序列化,反序列化的情况,用枚举应该会更好
16 楼 icewubin 2011-09-19  
suu 写道
博主厉害,只是有点小小疑问,静态内部类在外部类加载时不会初始化么?搜了下,说法不一,忘楼主从原因上解惑,谢谢

内部类也是个类啊,和外部类一样,什么时候会触发该类的初始化构成呢?当然是对该类的变量进行使用,或者是调用了针对该类的Class.forName()方法。
15 楼 suu 2011-09-18  
博主厉害,只是有点小小疑问,静态内部类在外部类加载时不会初始化么?搜了下,说法不一,忘楼主从原因上解惑,谢谢
14 楼 icewubin 2010-05-13  
pengqb 写道
icewubin 写道
pengqb 写道
Java中我最推荐的单例模式:够简单吧,呵呵
public enum Singleton {
  instance;
}

这种方式是有限制的,你如果enum用得多就知道了,enum有很多限制,毕竟不是普通的类。

还有就是enum的单例的效果是等价于饿汉式初始化方式的,并不是最理想的需要单例时才执行单例初始化代码的模式。

见:Effective java Second Edition 第二章第3条:用私有构造器或枚举类型强化Singleton属性。里面有各种单例模式的详细比较。

你说的我又不是不知道,你怎么这么照本宣读呢?

我不是说了,enum自身有限制的么?例如enum不能继承。

很多时候为了减少类的数量,或者某个单例类中有几个public static的公共方法,或者是有几个public static的常量,此时用我推荐的方式实现单例就是最完美的。

完美的定义:
1.加载这个类的时候不会提引发单例的初始化。

2.即使调用该类的public static方法或public static的常量也不会引提前引发单例的初始化。

3.只有在需要的时候才会初始化单例,而且不需要加同步控制,由JDK自身的classloader机制来完成高效的同步控制,这里的高效是值,只有第一次初始化的时候可能产生竞争,一旦初始化完毕不再产生同步竞争。

enum方式的单例只是符合上述第三条而已。碰到混合型功能的类,或者当前单例需要继承其他类,或者需要有Spring来管理一些有状态的bean的注入的话,enum就不能满足要求了。
13 楼 pengqb 2010-05-13  
icewubin 写道
pengqb 写道
Java中我最推荐的单例模式:够简单吧,呵呵
public enum Singleton {
  instance;
}

这种方式是有限制的,你如果enum用得多就知道了,enum有很多限制,毕竟不是普通的类。

还有就是enum的单例的效果是等价于饿汉式初始化方式的,并不是最理想的需要单例时才执行单例初始化代码的模式。

见:Effective java Second Edition 第二章第3条:用私有构造器或枚举类型强化Singleton属性。里面有各种单例模式的详细比较。
12 楼 icewubin 2010-05-08  
之所以说第三种,就是指前两种饿汉式和懒汉式各有优缺点,第三种包含前两者的优点而没有前两者的缺点,并不是单纯的追求代码简单,实际上第三种的代码并不少。
11 楼 icewubin 2010-05-08  
pengqb 写道
Java中我最推荐的单例模式:够简单吧,呵呵
public enum Singleton {
  instance;
}

这种方式是有限制的,你如果enum用得多就知道了,enum有很多限制,毕竟不是普通的类。

还有就是enum的单例的效果是等价于饿汉式初始化方式的,并不是最理想的需要单例时才执行单例初始化代码的模式。
10 楼 pengqb 2010-05-08  
Java中我最推荐的单例模式:够简单吧,呵呵
public enum Singleton {
  instance;
}
9 楼 拥抱变化之美 2009-05-13  
我以前也是这样写过,不过就是总爱遗漏 final 关键字。
8 楼 icewubin 2009-05-04  
wakin2003 写道

你的意思是利用静态类只在第一次被调用的时候初始化来实现只调用一次构造方法,既实现单例模式是吧?这个方法很特别,呵呵。不错。

是的,的确如此。
7 楼 wakin2003 2009-05-04  
icewubin 写道

wakin2003 写道
这样为啥是最佳的呢?内部类能解决多线程访问的问题么?呵呵。 就是利用Java的类加载机制,来变相的解决多线程访问的问题。

你的意思是利用静态类只在第一次被调用的时候初始化来实现只调用一次构造方法,既实现单例模式是吧?这个方法很特别,呵呵。不错。
6 楼 icewubin 2009-05-02  
天机老人 写道

我想问的是,为什么解决了线程问题就是最佳的了呢? 水平有限还忘LZ回答一下! 学习一下!

最佳是指:
1.运行效率大大优于懒汉式,因为懒汉式有一个同步过程(因为Java中无法像C++那样用双重检查,所以那个同步无法避开)。

2.同时又不像饿汉式那样,过早的触发初始化。这个过早是指:
如果有如下的变量:
public static int totalNum = 0;
如果是恶汉式的话,一调用这个变量,这个类就会初始化,而用类加载的方式的话,不会这么早就开始单例初始化。
5 楼 天机老人 2009-05-01  
我想问的是,为什么解决了线程问题就是最佳的了呢?
水平有限还忘LZ回答一下!
学习一下!
4 楼 icewubin 2009-03-05  
wakin2003 写道

这样为啥是最佳的呢?内部类能解决多线程访问的问题么?呵呵。

就是利用Java的类加载机制,来变相的解决多线程访问的问题。
3 楼 wakin2003 2009-03-05  
这样为啥是最佳的呢?内部类能解决多线程访问的问题么?呵呵。
2 楼 icewubin 2008-10-23  
zzx0421 写道

构造方法要声明为私有吧?

漏了,多谢,补上。
1 楼 zzx0421 2008-10-23  
构造方法要声明为私有吧?

相关推荐

Global site tag (gtag.js) - Google Analytics