讨论常用的单例设计模式:饿汉式(需要加锁保证线程安全)、懒汉式(天生线程安全)
单例设计模式要满足的特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
一、 饿汉式之属性获取
/**
* 单例模式之饿汉式1
* 属性获取
* @author shkstart
* @create 2021-03-02 10:41
*/
public class Singleton {
//构造器初始化
private Singleton() {
}
//
public static final Singleton singleton = new Singleton();
}
二、饿汉式之工厂方法获取
/**
* 单例模式之饿汉式2
* 方法获取获取
* @author shkstart
* @create 2021-03-02 10:41
*/
public class Singleton {
//构造器初始化
private Singleton() {
}
//自行创建共享对象
private static final Singleton singleton = new Singleton();
public static Singleton getInstance(){
return singleton;
}
}
三、饿汉式之静态代码块初始化
/**
* 单例模式之饿汉式3
* 静态代码块初始化
* @author shkstart
* @create 2021-03-02 10:41
*/
public class Singleton {
//构造器初始化
private Singleton() {
}
//自行创建共享对象
private static final Singleton singleton;
static {
singleton = new Singleton();
}
public static Singleton getInstance(){
return singleton;
}
}
四、懒汉式:在第一次调用方法时进行初始化
/**
* 懒汉式
* @author shkstart
* @create 2021-03-02 10:53
*/
public class Singleton {
private Singleton() {
}
private static final Singleton singleton;
public static Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
4.1 懒汉式线程安全实现 ---方法同步
/**
* 懒汉式
* @author shkstart
* @create 2021-03-02 10:53
*/
public class Singleton {
private Singleton() {
}
private static volatile Singleton singleton;
//方法体上加入synchronized关键字
//静态方法中 锁为当前类的class对象
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
4.2 懒汉式线程安全实现优化 ---双重判空
/**
* 懒汉式
* @author shkstart
* @create 2021-03-02 10:53
*/
public class Singleton {
private Singleton() {
}
private static volatile Singleton singleton;
//优化了多线程情况下的获取速度
public static Singleton getInstance(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
4.3 懒汉式线程安全实现再一步优化 ---静态内部类(推荐,解决线程安全的同时,性能更高)
在第一次调用方法时,内部类初始化单例对象,后面线程获取就直接返回
/**
* 懒汉式
*
* @author shkstart
* @create 2021-03-02 10:53
*/
public class Singleton {
private Singleton() {
}
private static class LazyHolder{
private static volatile Singleton SINGLETON = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.SINGLETON;
}
}