打字猴:1.700456945e+09
1700456945 ❑创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;
1700456946
1700456947 ❑需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)。
1700456948
1700456949
1700456950
1700456951
1700456952 设计模式之禅 7.3.4 单例模式的注意事项
1700456953
1700456954 首先,在高并发情况下,请注意单例模式的线程同步问题。单例模式有几种不同的实现方式,上面的例子不会出现产生多个实例的情况,但是如代码清单7-4所示的单例模式就需要考虑线程同步。
1700456955
1700456956 代码清单7-4 线程不安全的单例
1700456957
1700456958 public class Singleton{
1700456959
1700456960 private static Singleton singleton=null;
1700456961
1700456962 //限制产生多个对象
1700456963
1700456964 private Singleton(){
1700456965
1700456966 }
1700456967
1700456968 //通过该方法获得实例对象
1700456969
1700456970 public static Singleton getSingleton(){
1700456971
1700456972 if(singleton==null){
1700456973
1700456974 singleton=new Singleton();
1700456975
1700456976 }
1700456977
1700456978 return singleton;
1700456979
1700456980 }
1700456981
1700456982 }
1700456983
1700456984 该单例模式在低并发的情况下尚不会出现问题,若系统压力增大,并发量增加时则可能在内存中出现多个实例,破坏了最初的预期。为什么会出现这种情况呢?如一个线程A执行到singleton=new Singleton(),但还没有获得对象(对象初始化是需要时间的),第二个线程B也在执行,执行到(singleton==null)判断,那么线程B获得判断条件也是为真,于是继续运行下去,线程A获得了一个对象,线程B也获得了一个对象,在内存中就出现两个对象!
1700456985
1700456986 解决线程不安全的方法很有多,可以在getSingleton方法前加synchronized关键字,也可以在getSingleton方法内增加synchronized来实现,但都不是最优秀的单例模式,建议读者使用如代码清单7-3所示的方式(有的书上把代码清单7-3中的单例称为饿汉式单例,在代码清单7-4中增加了synchronized的单例称为懒汉式单例)。
1700456987
1700456988 其次,需要考虑对象的复制情况。在Java中,对象默认是不可以被复制的,若实现了Cloneable接口,并实现了clone方法,则可以直接通过对象复制方式创建一个新对象,对象复制是不用调用类的构造函数,因此即使是私有的构造函数,对象仍然可以被复制。在一般情况下,类复制的情况不需要考虑,很少会出现一个单例类会主动要求被复制的情况,解决该问题的最好方法就是单例类不要实现Cloneable接口。
1700456989
1700456990
1700456991
1700456992
1700456993 设计模式之禅 [:1700453936]
1700456994 设计模式之禅 7.4 单例模式的扩展
[ 上一页 ]  [ :1.700456945e+09 ]  [ 下一页 ]