单例模式
意在保证一个类只有一个实例,并提供一个全局访问点.
通过将类的构造器私有化,只向外提供一个单独的创建唯一对象的方法来实现一个类只创建一个对象.主要有三种实现 1. 饿汉模式 2. 懒汉模式 3.使用枚举实现单例.下面通过具体实例来分析如何在多线程的情况下仍能满足单例模式创建对象.
饿汉模式
1 | public class Singleton { |
这种方式不会影响到多线程的线程安全问题,因为类的装载机制在初始化对象的时候是保证不会有第二个线程进入的。但是有个很大的弊端是他不是lazy-loading
的,这回产生资源的浪费,比如创建完对象后,自始至终没用过。所以不推荐使用
懒汉模式
1 | public class Singleton { |
上面代码的第一种是不能保证线程安全的,多线程下会导致失效。而第二种使用静态内部类的方式实现能够实现线程安全得宜于类的加载机制,类似饿汉模式。但同时具有lazy-Loading
的特性。是常用的单例模式用法。
double-check
双重锁
双重锁结构只是为了满足多线程安全而建立的,是一种特殊的懒汉模式,思想同懒汉模式相同.
1 | public class DoubleCheck { |
实际上double-check也是懒汉模式的一种,能够保证线程安全。很完美。。
使用枚举创建单例
在stackoverflow中有一个问题What is an efficient way to implement a singleton pattern in Java?
这里的回答引用到了Effective Java 作者 Joshua Bloch对于单例的处理方式:使用枚举
1 | public enum SingletonEnum { |
这种方法等同与使用public的构造方法,并且比上面的更加简洁,并且即使面对复杂的反射与序列化也能够保证单一的实例.虽然现实代码中应用的较少,但是这种使用枚举类型是创建单例的最佳方法.
1 | public void testEnum() { |