今天在论坛看见一小段代码,不得不佩服作者(
blog)的创新精神。以前在使用Singleton的时候大多采用这样的方式:
但这里的问题是synchronization实际上只在
getInstance()第一次调用的时候需要,这个方法在多线程频繁调用的应用中必然会成为效率的瓶颈。
到了 java 1.5,Bob Lee提到了 Double-Checked Locking (DCL) ,并强调了是infamous DCL;这种做法强调了效率 (但 Bob Lee认为 volatile 不比 synchronized快,另外这种做法会产生更多的代码,所以仍然坚持使用plain old synchronization),并不将整个方法 synchronized,而是只对创建 Singleton进行同步,这样,线程进入 getInstance(),发现 instance 已经创建,就会直接返回instance,而不用在方法外等待。
在这种情况下,Singleton的实现代码一般是这样:
接下来是 Bob Lee的创新做法:
JLS将保证
Singleton instance只在第一次调用g
etInstance()的时候创建。优雅且快速!
java 代码
- public class Singleton {
- static Singleton instance;
- public static synchronized Singleton getInstance() {
- if (instance == null)
- instance = new Singleton();
- return instance;
- }
- }
到了 java 1.5,Bob Lee提到了 Double-Checked Locking (DCL) ,并强调了是infamous DCL;这种做法强调了效率 (但 Bob Lee认为 volatile 不比 synchronized快,另外这种做法会产生更多的代码,所以仍然坚持使用plain old synchronization),并不将整个方法 synchronized,而是只对创建 Singleton进行同步,这样,线程进入 getInstance(),发现 instance 已经创建,就会直接返回instance,而不用在方法外等待。
在这种情况下,Singleton的实现代码一般是这样:
java 代码
- static volatile Singleton instance;
- public static Singleton getInstance() {
- if (instance == null) {
- synchronized (Singleton.class) {
- if (instance == null)
- instance == new Singleton();
- }
- }
- return instance;
- }
接下来是 Bob Lee的创新做法:
java 代码
- static class SingletonHolder {
- static Singleton instance = new Singleton();
- }
- public static Singleton getInstance() {
- return SingletonHolder.instance;
- }