精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-18
huanglei7211 写道 nianien 写道 littcai 写道 第一种是延迟加载的,优
从多线程的角度考虑,会不会有并发问题呢? SingleTon 类在系统启动后就已经创建好了,不会产生并发问题,你可以去了解下静态类 能否给出解释? |
|
返回顶楼 | |
发表时间:2011-05-18
sswh 写道 nianien 写道 [quote name="kingkan"] 调用静态方法或属性不用实例化。 调用对象方法或属性肯定要实例化。 请问kingkan说法对不对? 我测试了一下,即使调用静态方法,静态代码块和静态字段都会初始化的 好像kingkan说的意思是 类不用实例化也可以调用类的静态方法。 这个说法没错,但和你说的应该不是一个意思。 你说的“调用静态方法,静态代码块和静态字段都会初始化的”,没错,是这样的。 关于类的初始化,在《深入Java虚拟机》中这样描述: 引用 Java虚拟机在首次主动使用类型时初始化它们。只有6种活动被认为是主动使用: 创建类的新实例, 调用类中声明的静态方法, 操作类或者接口中声明的非常量静态字段, 调用Java API中特定的反射方法, 初始化一个类的子类, 以及指定一个类作为Java虚拟机启动时的初始化类。 大概意思是,基本上对类上静态字段、方法的操作都会导致类的初始化。 但除了一种特殊情况以外: 如果使用的是静态常量(static final),并且常量值是一个编译时常量表达式, 这时候不会导致类被初始化。 http://skyuck.iteye.com/blog/902939 |
|
返回顶楼 | |
发表时间:2011-05-18
nianien 写道 赵精龙 写道 在哪看过,最好的单例模式是只含一个元素的enum
给出代码来,学习一下~ public enum Enum { INSTANCE; } |
|
返回顶楼 | |
发表时间:2011-05-18
最后修改:2011-05-18
nianien 写道 [quote="sswh]
public static void main(String[] args) throws ClassNotFoundException { Class.forName("my.SingleTon", false, Test.class.getClassLoader()); System.out.println("做点其他事情..."); SingleTon.getInstance(); } } [quote name="kingkan"] 调用静态方法或属性不用实例化。 调用对象方法或属性肯定要实例化。 请问kingkan说法对不对? 我测试了一下,即使调用静态方法,静态代码块和静态字段都会初始化的 在你调用Class.forName("my.SingleTon", false, Test.class.getClassLoader()); ,类装载器装入这个类的时候,该类的静态代码块和静态字段就会初始化。这跟你调用静态方法没有关系,当然啦,你调用这个类的静态方法的时候,类装载器就必须得先装载这个类了,除非这个类不存在,那么装载类,那么内部的静态块就会被初始化。 深入理解JVM书里描述: 引用 Java虚拟机在首次主动使用类型时初始化它们。只有6种活动被认为是主动使用: 创建类的新实例, 调用类中声明的静态方法, 操作类或者接口中声明的非常量静态字段, 调用Java API中特定的反射方法, 初始化一个类的子类, 以及指定一个类作为Java虚拟机启动时的初始化类。 |
|
返回顶楼 | |
发表时间:2011-05-19
skyuck 写道 nianien 写道 赵精龙 写道 在哪看过,最好的单例模式是只含一个元素的enum
给出代码来,学习一下~ public enum Enum { INSTANCE; } 你这代码能说明什么?延迟实例化,还是线程安全? |
|
返回顶楼 | |
发表时间:2011-05-19
public enum EnumSingleton implements Serializable {
INSTANCE; public void doSomething() {}; } 书上例子 枚举的单例!新的方法。如果jdk版本允许! |
|
返回顶楼 | |
发表时间:2011-05-19
nianien 写道 skyuck 写道 nianien 写道 赵精龙 写道 在哪看过,最好的单例模式是只含一个元素的enum
给出代码来,学习一下~ public enum Enum { INSTANCE; } 你这代码能说明什么?延迟实例化,还是线程安全? 你自己可以写代码测试一下,你介绍的那几种单例模式 都可以通过反射机制创建出不同的对象,而通过枚举实现的单例则不能 |
|
返回顶楼 | |
发表时间:2011-05-19
skyuck 写道 nianien 写道 skyuck 写道 nianien 写道 赵精龙 写道 在哪看过,最好的单例模式是只含一个元素的enum
给出代码来,学习一下~ public enum Enum { INSTANCE; } 你这代码能说明什么?延迟实例化,还是线程安全? 你自己可以写代码测试一下,你介绍的那几种单例模式 都可以通过反射机制创建出不同的对象,而通过枚举实现的单例则不能 的确不能再被实例化,但是它的实例化是不能延迟的 |
|
返回顶楼 | |
发表时间:2011-05-19
nianien 写道 个人认为下面是Java实现的最优的单例模式
这种实现方法采用内部静态类, 只在第一次调用getInstance方法的时候才实例化单例对象 如果不调用,就不会进行单例对象的实例化, 因此,既实现了延迟实例化,又不需要线程同步 引用 public class SingleTon { private SingleTon(){} public static SingleTon getInstance() { return SingleTonHolder.instance; } private static class SingleTonHolder{ private static SingleTon instance=new SingleTon(); } } 下面这种单例模式是应用最多的,同样不存在线程同步的问题 但是,不能实现延迟实例化 引用 public class SingleTon { private SingleTon(){} private static SingleTon s=new SingleTon(); public static SingleTon getInstance() { return s; } } 这种单例模式,和上面的实现差不多,虽然能够延迟单例对象的实例化,但是都是在同一时间范围内完成的 引用 public class SingleTon { private SingleTon(){} private static SingleTon s; static { s=new SingleTon(); } public static SingleTon getInstance() { return s; } } 下面这种就是 还有两种解决方案,不在本帖讨论范围之内 1.采用synchronized的关键字同步getInstance方法 2.采用synchronized的关键字同步代码段,双重是否为空的判断 ======================== Class.forName("SingleTon$SingleTonHolder"); |
|
返回顶楼 | |
发表时间:2011-05-20
zean 写道 nianien 写道 个人认为下面是Java实现的最优的单例模式
这种实现方法采用内部静态类, 只在第一次调用getInstance方法的时候才实例化单例对象 如果不调用,就不会进行单例对象的实例化, 因此,既实现了延迟实例化,又不需要线程同步 引用 public class SingleTon { private SingleTon(){} public static SingleTon getInstance() { return SingleTonHolder.instance; } private static class SingleTonHolder{ private static SingleTon instance=new SingleTon(); } } 下面这种单例模式是应用最多的,同样不存在线程同步的问题 但是,不能实现延迟实例化 引用 public class SingleTon { private SingleTon(){} private static SingleTon s=new SingleTon(); public static SingleTon getInstance() { return s; } } 这种单例模式,和上面的实现差不多,虽然能够延迟单例对象的实例化,但是都是在同一时间范围内完成的 引用 public class SingleTon { private SingleTon(){} private static SingleTon s; static { s=new SingleTon(); } public static SingleTon getInstance() { return s; } } 下面这种就是 还有两种解决方案,不在本帖讨论范围之内 1.采用synchronized的关键字同步getInstance方法 2.采用synchronized的关键字同步代码段,双重是否为空的判断 ======================== Class.forName("SingleTon$SingleTonHolder"); 跟你能看到内部类似的~ |
|
返回顶楼 | |