说起设计模式,java中总共有23中设计模式,我们最常见的也就属于单例设计模式了,它也是最简单的设计模式。
首先,什么是单例设计模式? 单例设计模式是在程序运行过程中,该程序中只能存在该类的一个对象。
单例设计模式书写方法:1. 构造方法私有化 2. 提供静态的方法供外部调用
单例设计模式的书写方式有很多中,比较常见的就是饿汉式和懒汉式。
饿汉式:
public class Singleton {
private static Singleton mInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return mInstance;
}
}
这种方式在类加载的时候就会创建对象,容易造成内存浪费。执行效率高,线程安全。
懒汉式:
public class Singleton {
private static SingletonmInstance =null;
private Singleton() {
}
public static SingletongetInstance() {
if (mInstance ==null) {
mInstance =new Singleton();
}
return mInstance;
}
}
在调用的时候才会创建对象,但是线程不安全。多线程调用时会出现问题。
public class Singleton {
private static SingletonmInstance =null;
private Singleton() {
}
public static SingletongetInstance() {
if (mInstance ==null) {
synchronized (Singleton.class) {
if (mInstance ==null) {
mInstance =new Singleton();
}
}
}
return mInstance;
}
}
在获取对象时加上synchronized关键字,能够保证在多线程调用时不会出现线程安全问题,但是相对来说效率较低。但这种方式并不完善,还是会极小概率出现问题。
由于java在创建对象时有以下三个步骤:
1. 开辟一块内存空间
2. 初始化对象
3. 将初始化好的对象指向内存空间
然而这个执行顺序并非固定,有可能会按照1->2->3的顺序执行,也有可能会执行1->3->2的顺序。当按照132顺序执行时,会导致对象未被初始化就指向了内存空间,从而出现问题。此使使用volatile关键字,可以有效避免这个问题。
volatile关键字的作用主要有以下两点:
1. 防止指令重排序
2. 保持内存可见性
因此修改后的代码如下:
public class Singleton {
private volatile static SingletonmInstance =null;
private Singleton() {
}
public static SingletongetInstance() {
if (mInstance ==null) {
synchronized (Singleton.class) {
if (mInstance ==null) {
mInstance =new Singleton();
}
}
}
return mInstance;
}
}
网友评论