两种不同的单例模式
单例模式顾名思义就是一种只有一个实例的代码模式,简单的来说就是只能new一次.
饿汉模式
饿汉模式:上述代码的执行时机是在Singleton类在JVM加载的时候,也就是说Singleton会在JVM第一次加载的时候就NEW一个对象.并且别的线程只能获取singleton而不能改变他的值.如果说当其他线程中不小心再一次NEW了一个对象编译器就会报错.
懒汉模式
懒汉模式:在这种模式下代码不会一开始就NEW一个对象,只有当你需要一个对象的时候他才会帮你NEW一个对象.但是能这个模式他会改变singlentonlazy的值这也就会有线程安全的问题
单例模式中存在的线程安全问题
当多个线程同时修改一个变量就会发生线程安全问题.上述的两种模式,饿汉模式只能读取变量所以并不会发生线程安全问题.懒汉模式中new操作并不是一个原子而且'SingletonLazy==null'这一语句会触发内存可见性,所以需要对懒汉模式进行一些改进使得他是线程安全的.
上述代码就是安全的代码了.通过加锁,volatile,双重if来保证安全.
其中对双重if进行进一步的解释:由于并不是每次调用都需要加锁,所以当一个if是判断是不是第一次进行NEW.第二个if是防止多个线程阻塞时时间过长,有可能别的线程改变了singlentonlazy的值.防止再次NEW一个.