最近重新学习了一下单例模式,写博客总结一下,有错误或者另外的方法欢迎指出
单例模式的六种常见形式
一、饿汉式:直接创建对象,无线程安全问题
1.1直接实例化饿汉式(简洁直观)
package com.lp.singleton;
//1.1直接实例化饿汉式(简洁直观)
/*
直接创建实例对象
构造器私有化
自行创建,用静态变量保存
final用来强调单例,可以不加
*/
public class HungrySingleton1 {
public static final HungrySingleton1 INSTANCE=new HungrySingleton1();
private HungrySingleton1(){}
}
1.2枚举式(最简洁)
package com.lp.singleton;
/*
1.2枚举式(最简洁)
只声明一个,表示限定为单例
*/
public enum HungrySingleton2{
INSTANCE
}
1.3静态代码块饿汉式(适合复杂饿汉式)
package com.lp.singleton;
/*
* 1.3静态代码块饿汉式(适合复杂饿汉式)
* 通过静态代码块创建实例
*/
public class HungrySingleton3 {
public static final HungrySingleton3 INSTANCE;
static {
INSTANCE=new HungrySingleton3();
}
private HungrySingleton3(){}
}
二、懒汉式:延迟创建对象
2.1线程不安全(适用于单线程)
package com.lp.singleton;
/*
*2.1线程不安全(适用于单线程)
* 构造器私有化
* 用静态变量修饰
* 提供静态变量方法获取对象
*/
public class lazySingleton1 {
private static lazySingleton1 instance;
private lazySingleton1() {
}
public static lazySingleton1 getInstance() {
if (instance == null) {
instance = new lazySingleton1();
}
return instance;
}
}
2.2线程安全(适用于多线程)
package com.lp.singleton;
/*
*2.2线程安全(适用于多线程)
* 构造器私有化
* 用静态变量修饰
* 提供静态变量方法获取对象
* 使用synchronized锁住对象
*/
public class lazySingleton2 {
//加volatile防止重排序,保证线程安全
private volatile static lazySingleton2 instance;
private lazySingleton2() {
}
public static lazySingleton2 getInstance() {
if(instance == null) {
synchronized (lazySingleton2.class) {
if (instance == null) {
instance = new lazySingleton2();
}
}
}
return instance;
}
}
2.3静态内部类(适用于多线程)
package com.lp.singleton;
/*
*2.3静态内部类(适用于多线程)
* 构造器私有化
* 用静态变量修饰
*在静态内部类被加载和初始化时,才创建INSTANCE实例对象
* 静态内部类单独加载和初始化,不会随着外部类的加载和初始化而初始化
*/
public class lazySingleton3 {
private lazySingleton3() {
}
private static class Inner {
public static final lazySingleton3 INSTANCE=new lazySingleton3();
}
public static lazySingleton3 getInstance(){
return Inner.INSTANCE;
}
}