【Java单例模式】Java单例模式之懒汉模式线程安全
2017-03-22 17:34
357 查看
单例模式是设计模式中用得比较多的一种设计模式,它的主要优点有:
1.访问受控,保证访问的是唯一的实例。
2.由于只有一个实例,所以节省资源。
缺点:
灵活性低,如果对象的应用场景多变,则不适用单例模式。
这样我们就得到了一个类型为SingleTon的静态变量,接下来,我们就要控制这个类,不能被任意的new出来,这个就是实现了单例模式唯一性的根本,代码如下:
这种模式的单例在非并发环境下是可靠的,我们知道,我们保证类是单例的代码关键是
if(singleTon == null)
并且java中new是不具有原子性的(涉及到赋值问题),所以,在并发环境下,是可能执行了多次的new操作,造成实例非唯一性。
上述懒汉产生多个实例造成单例失效的原因是在高并发环境下可能同时有2个或以上的线程访问getInstance()类方法,又因为new操作不具有原子性,所以会导致产生2个实例的问题。
因此,我们可以:
1.通过添加synchronized来修饰getInstance()方法,简单有效粗暴,但是往往暴力使用同步方法带来的问题都是一样的,就是惨重的效率代价~
2.通过添加synchronized来同步部分代码块,并且通过volatile来防止指令重排,代码如下:
上述方法就是传说中的DCL双重检查锁定单例(JDK1.5之后的版本)
1.访问受控,保证访问的是唯一的实例。
2.由于只有一个实例,所以节省资源。
缺点:
灵活性低,如果对象的应用场景多变,则不适用单例模式。
1.如何实现单例模式?
1.1 懒汉模式(线程不安全)
想要实现单例,莫非就是要适用static关键字,如下声明一个对象:public class SingleTon { private static SingleTon singleTon = null; }
这样我们就得到了一个类型为SingleTon的静态变量,接下来,我们就要控制这个类,不能被任意的new出来,这个就是实现了单例模式唯一性的根本,代码如下:
public class SingleTon { private static SingleTon singleTon = null; //把构造函数设置为private,防止被new实例化 private SingleTon() {} public static SingleTon getInstance() { //每次调用SingleTon.getInstance()时返回的都是singleTon唯一对象 if( singleTon == null ) { singleTon = new SingleTon(); } return singleTon; }
这种模式的单例在非并发环境下是可靠的,我们知道,我们保证类是单例的代码关键是
if(singleTon == null)
并且java中new是不具有原子性的(涉及到赋值问题),所以,在并发环境下,是可能执行了多次的new操作,造成实例非唯一性。
1.2如何解决?
为了解决问题,首先就要明白问题产生的原因:上述懒汉产生多个实例造成单例失效的原因是在高并发环境下可能同时有2个或以上的线程访问getInstance()类方法,又因为new操作不具有原子性,所以会导致产生2个实例的问题。
因此,我们可以:
1.通过添加synchronized来修饰getInstance()方法,简单有效粗暴,但是往往暴力使用同步方法带来的问题都是一样的,就是惨重的效率代价~
2.通过添加synchronized来同步部分代码块,并且通过volatile来防止指令重排,代码如下:
public class SingleTon { private static SingleTon singleTon = null; private SingleTon() {} public static SingleTon getInstance() { if( singleTon == null ) { synchronized( SingleTon.class ) { if( singleTon == null ) { singleTon = new SingleTon(); } } } return singleTon; } }
上述方法就是传说中的DCL双重检查锁定单例(JDK1.5之后的版本)
相关文章推荐
- 单例模式之懒汉模式且线程安全
- Java练习题-编写一个线程安全的延迟加载单例模式(懒汉模式)
- Java练习题-编写一个线程安全的延迟加载单例模式(懒汉模式)
- 关于java (懒汉)单例模式是否存在线程安全的问题
- 关于多线程在简单的懒汉模式下线程安全问题的解决
- 设计模式之懒汉单例非线程安全
- 设计模式 Singleton 单例 懒汉,线程安全
- [置顶] Java 多线程学习笔记(十一) 单例设计模式(延迟加载/懒汉模式)DCL解决线程安全问题
- Java单例模式之饿汉模式与懒汉模式
- java单例模式之饿汉模式与懒汉模式
- 线程安全的Java单例模式——如何正确地写出单例模式
- 利用classloader机制创建线程安全的懒汉单例模式
- Java单例模式之饿汉模式与懒汉模式
- 线程安全的单例懒汉模式(互斥锁)
- java单例模式和懒汉模式代码
- C++单例模式(懒汉和饿汉)与线程安全
- 线程安全的"懒汉"单例模式
- 单例模式之懒汉模式的线程安全解决方法
- 线程安全的懒汉模式单例模实现
- JAVA单例(懒汉模式)线程安全