单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
Singleton类,定义一个getInstance静态方法,允许客户访问它的唯一实例。
1、懒汉式单例模式
1 | public class Singleton { |
- 构造方法私有,防止外界利用构造方法进行实例化(但实际通过发射亦可以在外部调用私有构造方法,这里不讨论)
- getInstance是外界唯一能够访问的入口
- 若实例存在,那么直接返回。全局只有一个对象
1 | Singleton s1 = Singleton.getInstance(); |
2、线程安全的懒汉式
但是懒汉式的单例模式并不是线程安全的,在多线程并发的情况下可能会出现多个实例。要实现线程安全,要对getInsance方法进行改造使懒汉式变得线程安全。
- 对getInstance方法使用同步方法或者同步代码块
1
2
3
4
5
6public static synchronized Singleton getInstance_1(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
虽然多线程下是安全的,但是方法的整个事务判断全部被同步,这种写法效率不高!
- 双重检查锁定
1
2
3
4
5
6
7
8
9
10public static Singleton getInstance_2(){
if(instance == null){
synchronized (instance){
if(instance == null){
instance = new Singleton();
}
}
}
return null;
}
双重检查模式先判断实例是否存在,不存在再进行加锁处理。相比上一种写法提高了效率。
- 静态内部类
1
2
3
4
5
6
7
8
9
10
11
12public class Singleton {
private Singleton(){}
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static final Singleton getInstance_3() {
return LazyHolder.INSTANCE;
}
}
相比上两种写法,效率要高!
3、饿汉式单例
1 | public class SingletonA { |
饿汉式单例在类创建的同时就创建了一个静态的实例变量,所以天生是线程安全的!
4、懒汉式和饿汉式的比较
- 饿汉式天生线程安全,懒汉式需要进行上文的三种处理
- 性能加载和资源:饿汉式在创建类时就会开辟内存空间实例化一个静态的变量,不管你是否使用它都在那里;懒汉式是一种延时加载的方式,
在第一次调用getInstance方法时实例化对象。
本文作者:
肖鹏
本文链接: http://www.xiaopeng.pro/articles/f1601c3e.html
版权声明: 本原创文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
本文链接: http://www.xiaopeng.pro/articles/f1601c3e.html
版权声明: 本原创文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!