单例模式(饿汉模式,懒汉模式)
一.饿汉模式
饿汉模式就是在类加载的时候就开始创建成员变量
二.懒汉模式
懒汉模式就是在调用这个方法的才去创建这个实例
三.线程安全问题
在饿汉模式中是不会出现线程安全问题的因为对它的变量只是读但不改变
在懒汉模式中是可能出现这个线程安全问题的因为对它所创建的变量会读也会写
那么导致它线程不安全的原因是什么?
假设有两个线程,第一个线程先去访问的时候同样第二个线程也可能会访问那么此时他们就会创建两个实例那么就出现了线程安全问题
那么怎么改变让它线程安全呢
那么我们就想到使用加锁的方式(synchronized)
那么这样就使得当多个线程访问的时候就只有一个实例变量
但是假设当你第一个线程已经访问了并且创建好了实例那么你第二个线程再次去访问的时候那么是不是还是会进行加锁解锁但已经有了结果就该直接返回那么是不是就多消耗了资源所以我们应该还在外面加上一个if语句来使得这个变的更高效
但是可能会出现指令重排序的问题
singTon2 = new SingTon2();
它会有三个指令分别为1.申请内存空间2.使用构造方法来初始化实例3.赋值给singTon2引用
系统可能有时候想到优化就会将这个顺序变成132但是也不会影响整个结果的改变但是这里若变成132的话当第一个线程去访问的时候在这个132的顺序下正好将3走完(此时的引用不是null是一个尚未初始化的对象而已)此时线程被调度走了就开始让第二个线程重新开始那么它此时就会读到这个3的引用然后就会直接访回结果那么此时数据就错误
那么我们就要使用volatile它可以禁止指令重排序。