关键词搜索

源码搜索 ×
×

程序设计之Java设计模式(单例模式)

发布2013-09-27浏览1339次

详情内容

1、普通单例模式

此类缺陷:无法应对多线程问题

  1. package com.boonya.pattern.singleton;
  2. /**
  3. * 单例示例
  4. * <li>文件名称: Singleton</li>
  5. * <li>文件描述: $单例示例类</li>
  6. * <li>内容摘要: 单例的创建</li>
  7. * <li>完成日期:2013-9-27</li>
  8. * <li>示例编写: BOONYACHENGDU@GMAIL.COM</li>
  9. * <li>应用场景:频繁使用的对象且值不变,一如组件之类的对象</li>
  10. */
  11. public class Singleton
  12. {
  13. /**
  14. * 无论是否调用都会实例化
  15. */
  16. private static Singleton singleton=new Singleton();
  17. /**
  18. * 确保外部不能实例化,即使用new关键字无效
  19. */
  20. private Singleton(){
  21. System.out.println("singleton constructor");
  22. }
  23. /**
  24. * 必须确保同步,否则多线程情况下值不统一 但 synchronized 关键字使用会降低系统性能
  25. */
  26. public static /*synchronized*/ Singleton getInstance(){
  27. return singleton;
  28. }
  29. }

2、懒加载单例模式

此类缺陷:使用多线程时系统性能明显下降

  1. package com.boonya.pattern.singleton;
  2. /**
  3. * 单例示例
  4. * <li>文件名称: LazySingleton</li>
  5. * <li>文件描述: $单例示例类</li>
  6. * <li>内容摘要: 单例的创建</li>
  7. * <li>完成日期:2013-9-27</li>
  8. * <li>示例编写: BOONYACHENGDU@GMAIL.COM</li>
  9. * <li>应用场景:频繁使用的对象且值不变,一如组件之类的对象</li>
  10. */
  11. public class LazySingleton
  12. {
  13. /**
  14. * 调用的时候再实例化
  15. */
  16. private static LazySingleton singleton=null;
  17. /**
  18. * 确保外部不能实例化,即使用new关键字无效
  19. */
  20. private LazySingleton(){
  21. System.out.println("singleton constructor");
  22. }
  23. /**
  24. * 必须确保同步,否则多线程情况下值不统一(线程执行先后可能判断为null)
  25. */
  26. public static synchronized LazySingleton getInstance(){
  27. if(singleton==null){
  28. singleton=new LazySingleton();
  29. }
  30. return singleton;
  31. }
  32. }

3、加强(plus)单例

此类缺陷:使用反射机制时,会强行调用单例类的私有构造器,生成多个实例

  1. package com.boonya.pattern.singleton;
  2. /**
  3. * 单例示例
  4. * <li>文件名称: PlusSingleton</li>
  5. * <li>文件描述: $单例示例类</li>
  6. * <li>内容摘要: 单例的创建</li>
  7. * <li>完成日期:2013-9-27</li>
  8. * <li>示例编写: BOONYACHENGDU@GMAIL.COM</li>
  9. * <li>应用场景:频繁使用的对象且值不变,一如组件之类的对象</li>
  10. */
  11. public class PlusSingleton
  12. {
  13. /**
  14. * 确保外部不能实例化,即使用new关键字无效
  15. */
  16. private PlusSingleton(){
  17. System.out.println("singleton constructor");
  18. }
  19. /**
  20. * 内部类JVM初始换调用
  21. */
  22. private static class SingletonObject{
  23. private static PlusSingleton singleton=new PlusSingleton();
  24. }
  25. /**
  26. * 不需要考虑多线程问题
  27. */
  28. public static PlusSingleton getInstance(){
  29. return SingletonObject.singleton;
  30. }
  31. }

4、序列化单例

此类缺陷:序列化和反序列化都有可能会破坏单例

  1. package com.boonya.pattern.singleton;
  2. import java.io.Serializable;
  3. /**
  4. * 单例示例
  5. * <li>文件名称: Singleton</li>
  6. * <li>文件描述: $单例示例类</li>
  7. * <li>内容摘要: 单例的创建</li>
  8. * <li>完成日期:2013-9-27</li>
  9. * <li>示例编写: BOONYACHENGDU@GMAIL.COM</li>
  10. * <li>应用场景:频繁使用的对象且值不变,一如组件之类的对象 序列化操作需慎重</li>
  11. */
  12. @SuppressWarnings("serial")
  13. public class SerializableSingleton implements Serializable
  14. {
  15. private String context;
  16. public String getContext()
  17. {
  18. return context;
  19. }
  20. public void setContext(String context)
  21. {
  22. this.context = context;
  23. }
  24. /**
  25. * 无论是否调用都会实例化
  26. */
  27. private static SerializableSingleton instance=new SerializableSingleton();
  28. /**
  29. * 确保外部不能实例化,即使用new关键字无效
  30. */
  31. private SerializableSingleton(){
  32. System.out.println("singleton constructor");
  33. context="SerializableSingleton";
  34. }
  35. /**
  36. * 获取单例对象
  37. */
  38. public static SerializableSingleton getInstance(){
  39. return instance;
  40. }
  41. /**
  42. * 阻止生成新的实例,总是返回当前对象(此方法不可去掉否则序列化和反序列化会出错)
  43. */
  44. private Object readResolve(){
  45. return instance;
  46. }
  47. }

5、性能和注意事项

     (1)、频繁使用的对象且值不变,一如组件之类的对象建议使用单例。此处建议使用懒加载方式,使用的时候再实例化,降低JVM初始化static 时new实例化对象消耗性能,减少GC机制的执行。

    (2)、考虑是否会在多线程中使用到,多线程中使用单例消耗性能严重。

    (3)、使用单例时,尽量不要使用序列化操作,危险难以预测,最好是具体问题具体分析。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载