两种比较“强壮”的单例代码。
2015-08-08 21:14
477 查看
第一种:
public class SingletonClass{ private static SingletonClass instance = null; public static SingletonClass getInstance(){ if(instance == null){ synchronized(SingletonClass.class){ if(instance == null){ instance = new SingletonClass(); } } } return instance; } private SingletonClass(){ } }
此种方法采用了将构造方法改为“private”来修饰,这样就使得用户无法通过用new的方式来获得这个类的实例,但此类提供了一个供外部获得唯一实例的static方法getInstance(),当getInstance()方法第一次被调用时instance这个属性一定是为空的,当instance为空的时候要new一个实例出来,new出的这个实例也是程序运行过程中唯一的实例。
<span style="white-space:pre"> </span>if(instance == null){ synchronized(SingletonClass.class){ if(instance == null){ instance = new SingletonClass(); } } } return instance;
这是getInstance()方法中的全部代码,我们先看synchronized(){}这段,为什么这是一个“强壮”的单例呢,就是因为下面这条语句synchronized(){},如果不加synchronized(){}的话如果有多线程同时来调用getInstance()方法,就会可能就会导致单例模式的失效,出现多个实例。例如:A和B先后调用getInstance(),A线程第一次调用getInstance()方法时判断if为空,程序将会向下执行new实例的代码,不用多想一定会new一个实例,但当A想往下执行new一个新实例时CPU将控制交给了B线程,B在执行if语句时也判断为空,也不用多想,它执行了下面语句new出一个实例,些时CPU又回到A线程执行下面创建实例的代码,这时就出现了单例类矛盾的出现了两个实例。
所以,使用synchronized(){}代码是将判断instance是否为空和为空之后new实例的的代码在被多个线程调用的过程中只能有一个线程执行。大家会看到为什么要有两个if(instance == null)的判断呢,这是因为如果没有最外面的if判断时每次调用getInstance()方法时都会执行synchronized(){}代码,但每次执行synchronized(){}代码会比较慢,
所以考虑到性能的原因最外面先判断instance是否为空在决定是否执行synchronized(){}代码。
第二种:
public class SingletonClass { private static class SingletonClassInstance { private static final SingletonClass instance = new SingletonClass(); } public static SingletonClass getInstance() { return SingletonClassInstance.instance; } private SingletonClass() { } }
第二程实现的单例的方法使用了static的内部类,getInstance()方法返回的是内部类中instance属性,内部类内的instance属性用static final修饰,不管调用getInstance()方法被调用多少次,或被多个线程同时调用,都只会有一个实例存在。第二种方法比较推荐,只是使用了简单的内部类。
相关文章推荐
- 为什么和其他语言相比C语言是快速的语言
- python中的__metaclass__
- PyQt5初级教程--PyQt5中的对话框[7/13]
- Java中synchronized的使用注意
- C语言:顺序结构(数组)的循环队列
- github下fork后如何同步源的新更新
- github下fork后如何同步源的新更新
- python thread学习
- Java适配器设计模式
- hunnu11562:The Triangle Division of the Convex Polygon(第n个卡特兰数取模)
- jdk5-7特性
- java 加密
- Spring的注解配置与XML配置之间的比较
- java注解例子
- JAVA解析XML之DOM方式
- leetcode_Valid Anagram_easy
- C#高级编程八十天----异常类
- python正则表达式 re (二)match与search
- ubuntu 建立eclipse桌面快捷方式
- C++中数字与字符串之间的转换