java中单例模式是一种常见的设计模式,以下是它的特点:


  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例

第一种(懒汉,线程不安全):

 1 public class Singleton {  
 2     private static Singleton instance;  
 3

private Singleton (){}   
 4     public static Singleton getInstance() {  
 5     if (instance == null) {  
 6         instance = new Singleton();  
 7     }  
 8     return instance;  
 9     }  
10 }  
11 

 懒汉式是典型的时间换空间,就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间

 由于懒汉式的实现是线程安全的,这样会降低整个访问的速度,而且每次都要判断.

第二种(懒汉,线程安全):

 1 public class Singleton {  
 2     private static Singleton instance;  
 3

private Singleton (){}
 4     public static synchronized Singleton getInstance() {  
 5     if (instance == null) {  
 6         instance = new Singleton();  
 7     }  
 8     return instance;  
 9     }  
10 }  
11 

第三种(饿汉):

1 public class Singleton {  
2     private static Singleton instance = new Singleton();  
3

private Singleton (){}
4     public static Singleton getInstance() {  
5     return instance;  
6     }  
7 }  
8 

第四种(饿汉,变种):

 1 public class Singleton {  
 2     private Singleton instance = null;  
 3     static {  
 4     instance = new Singleton();  
 5     }  
 6

private Singleton (){}
 7     public static Singleton getInstance() {  
 8     return this.instance;  
 9     }  
10 }  
11 

表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始化即实例化instance。

第五种(静态内部类):

 1 public class Singleton {  
 2     private static class SingletonHolder {  
 3     private static final Singleton INSTANCE = new Singleton();  
 4     }  
 5

private Singleton (){}
 6     public static final Singleton getInstance() {  
 7         return SingletonHolder.INSTANCE;  
 8     }  
 9 }  
10 

优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading

第六种(枚举):

1 public enum Singleton {  
2     INSTANCE;  
3     public void whateverMethod() {  
4     }  
5 }  
6 

优点:不仅能避免多线程同步问题,而且还能防止反序列化

第七种(双重校验锁):

 1 public class Singleton {  
 2     private volatile static Singleton singleton;  
 3

private Singleton (){}   
 4     public static Singleton getSingleton() {  
 5     if (singleton == null) {  
 6         synchronized (Singleton.class) {  
 7         if (singleton == null) {  
 8             singleton = new Singleton();  
 9         }  
10         }  
11     }  
12     return singleton;  
13     }  
14 }  
15 

总结

有两个问题需要注意:

1、如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些

servlet容器对每个

servlet使用完全不同的类  装载器,这样的话如果有两个

servlet访问一个单例类,它们就都会有各自的实例。

2、如果

Singleton实现了

java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。

对第一个问题修复的办法是:

 1 private static Class getClass(String classname)      
 2                                          throws ClassNotFoundException {     
 3       ClassLoader classLoader = Thread.currentThread().getContextClassLoader();     
 4       
 5       if(classLoader == null)     
 6          classLoader = Singleton.class.getClassLoader();     
 7       
 8       return (classLoader.loadClass(classname));     
 9    }     
10 }  
11 

对第二个问题修复的办法是:

 1 public class Singleton implements java.io.Serializable {     
 2    public static Singleton INSTANCE = new Singleton();     
 3       
 4    protected Singleton() {     
 5         
 6    }     
 7    private Object readResolve() {     
 8             return INSTANCE;     
 9       }    
10 }   
11 

单例 (JAVA)的更多相关文章

  1. 单例 ------ JAVA实现

    单例:只能实例化一个对象,使用场景比如打印机. 最推荐的是采用饿汉式:双重校验锁用到了大量的语法,不能保证这些语法在所用场合一定没问题,所以不是很推荐:总之简单的才是最好的,就饿汉式!!! C++ 创 ...

  2. javaWeb项目中到底什么是单例,多例

    你用杯子喝可乐,喝完了不刷,继续去倒果汁喝,就是单例.你用杯子喝可乐,直接扔了杯子,换个杯子去倒果汁喝,就是多例. 数据库连接池就是单例模式,有且仅有一个连接池管理者,管理多个连接池对象. 1. 什么 ...

  3. java 单例

    Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉式单例. 饿汉式和懒汉式区别 从名字上来说,饿汉和懒汉, 饿汉就是类一旦加载,就把单例初始化完成,保证 ...

  4. Java设计模式之单例

    一.Java中的单例: 特点: ① 单例类只有一个实例 ② 单例类必须自己创建自己唯一实例 ③ 单例类必须给所有其他对象提供这一实例 二.两种模式: ①懒汉式单例<线程不安全> 在类加载时 ...

  5. java单例的几种实现方法

    java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...

  6. Java 多线程之单例设计模式

    转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...

  7. java单例类/

    java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...

  8. java单例-积木系列

    一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档.   懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒 ...

  9. 如何防止JAVA反射对单例类的攻击?

    在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...

随机推荐

  1. 回忆一次面试Android研发的问题

    有NDK开发JNI程序经验优先 intent   intentfileter 阿里云 线程,异步 1.图片缓冲2.解压3.获取搜索记录 4.在安卓开发过程中用到那些框架

  2. "Project facet Java version 1.7 is not supported"的问题解决的办法

    问题描述 在eclipse中,从SVN中检出project代码,拖拽式部署到local server中的时候,报出以下错误: 问题分析 问题产生的原因是,SVN中的代码是采用java 1.7开发编译的 ...

  3. 基于MATLAB的adaboost级联形式的人脸检测实现

    很早之前就做过一些关于人脸检测和目标检测的课题,一直都没有好好总结出来,趁着这个机会,写个总结,希望所写的内容能给研究同类问题的博友一些见解和启发!!博客里面涉及的公式太繁琐了,直接截图了. 转载请注 ...

  4. ZOJ 3494 BCD Code(AC自动机+数位DP)

    BCD Code Time Limit: 5 Seconds      Memory Limit: 65536 KB Binary-coded decimal (BCD) is an encoding ...

  5. 【Debug 报异常】Debug打断点报错

    用DEBUG启动项目,项目中打断点的,然后会报异常 解决方法: 第一步: 项目-->Java编译器-->Classfile Generation 复选框 全部勾选 第二步: 替换当前文件运 ...

  6. php代码效率测试

    对于一个被加载的页面,而遇到会卡的原因 ,代码量大,为了减少一句话分析,就采用分段式判断. 从php手册了解到,使用microtime函数,具体方法可参见php手册对这函数的用法 定义get_exec ...

  7. 记一次小团队Git实践(上)

    公司规模不大,成立之初,选择了svn作为版本控制系统.这对于用惯了git的我来说,将就了一段时间后,极为不爽,切换到git-svn勉强能用.随后,因为产品需要发布不同的版本,而git-svn对远程分支 ...

  8. iOS 关于iOS开发中的delegate

    有A.B两个对象,A要完成某件事,想让B帮它做. 这时候,A中就要实例化一个B的对象b,A还要在头文件中声明协议,然后在B中实现协议中对应的方法. 这时候再把A的delegate设置为b,在需要的地方 ...

  9. docker 1.0.0发布以及一个bug依赖apparmor_parser

    6月10号docker 1.0稳定版本发布,找了台ubuntu的机器,装了下 ubuntu version:12.04 docker version:1.0.0 装docker的步骤可以看官方文档:h ...

  10. 【原】iOS学习40网络之数据安全

    在互联网发展趋势迅猛的今天,数据安全的重要性日趋凸显.也成为我们必须了解的互联网知识. 在移动互联网浪潮下,用户的资金安全.企业的信息安全都是我们实际开发中必须考虑的内容.