1、单例模式
单例模式可以分为两种,一种为懒汉式,另外一种为饿汉式;在日常的web开发过程中,使用到的bean注入,就是使用的单例设计模式;使用单例模式的好处是一次创建,到处使用。
1.1 懒汉式单例模式
懒汉式设计模式即在类加载的时候不会创建对象,需要主动调用类中创建对象的方法完成对象创建。下面是普通的懒汉式代码示例:
public class SingleMode {
/**
* 懒汉式,在调用方法的时候创建实例
*/
public static SingleMode singleMode;
/**
* 普通懒汉式获取示例实现
* @return
*/
public synchronized static SingleMode createSingle(){
if(singleMode==null){
singleMode = new SingleMode();
}
return singleMode;
}
}
懒汉式在并发情况下会存在创建多个示例的情况,因此在普通懒汉式基础上使用双重检测机制,来避免并发情况下创建多个示例的问题。双重检测的原理是首先判断示例是否已经创建,没有创建则使用synchronized修饰创建示例代码块,在修饰代码块中再次判断对象是否已经创建,没有创建则进行创建;需要注意的是,懒汉式中的属性是使用volatile关键字修饰,使用该关键字修饰的作用是可以保证多线程情况下,某一个现场修改了该属性,其他线程是可以感知的,另外也保证了代码编译时的指令重排序问题。懒汉式双重检测代码示例:
public class SingleMode {
/**
* 懒汉式双重检查机制实现
* @return
*/
// volatile关键字修饰的属性,修改该值多线程之间可见,禁止编译时指令重排序,保证线程安全
public volatile static SingleMode lazySingleMode;
public static SingleMode getSingleMode(){
if(lazySingleMode==null){
synchronized (SingleMode.class){
if (lazySingleMode==null){
lazySingleMode = new SingleMode();
}
}
}
return lazySingleMode;
}
}
1.2 单例模式饿汉式
饿汉式单例模式,在类加载的时候已经完成对象创建,后面用户线程只需要调用获取对象方法得到对象即可,该模式的缺点是资源浪费,对象不需要被使用的情况下已经创建了该对象;饿汉式代码示例:
public class SingleMode {
/**
* 饿汉式,在类加载的时候创建对象
*/
public static final SingleMode single = new SingleMode();
private SingleMode(){}
public static SingleMode getSingle(){
return single;
}
}