什么是单例模式(Singleton Pattern)
为什么要用单例模式
节省内存空间,避免重复的创建和销毁对象,可以提高性能。
怎么样使用单例模式
一. 饿汉方式
/**
* 饿汉模式 - 1 线程安全
*
* @Author: zxs
* @Date: 2019/8/26
*/
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
/**
* 饿汉模式 - 2 线程安全
*
* @Author: zxs
* @Date: 2019/8/26
*/
public class Singleton2 {
private static Singleton2 instance;
{
instance = new Singleton2();
}
private Singleton2() {
}
public static Singleton2 getInstance() {
return instance;
}
}
饿汉模式总结
优点: 写法简单 线程安全
缺点: 类装载的时候就实例化,启动较慢.如果类没有使用过,造成内存空间浪费
二. 懒汉方式
/**
* 懒汉模式 - 1 线程不安全
*
* @Author: zxs
* @Date: 2019/8/26
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
/**
* 懒汉模式 - 2 线程安全
*
* @Author: zxs
* @Date: 2019/8/26
*/
public class Singleton2 {
private static Singleton2 instance;
private Singleton2() {
}
public static synchronized Singleton2 getInstance() {
if(instance == null){
instance = new Singleton2();
}
return instance;
}
}
懒汉模式总结
优点:
启动速度快,如果没使用过这个实例,则不会初始化该实例 不会操作内存空间的浪费
缺点:
懒汉模式 - 1 多线程不安全 if(instance == null){} 会有多个线程同时进入 导致重复创建对象
懒汉模式 - 2 解决了多线程不安全问题 但是 synchronized关键字 在多线程中效率不高
三. 双重检查锁方式
/**
* 双重检查锁
* @Author: zxs
* @Date: 2019/8/26
*/
public class Singleton {
/**
* 由于 JVM 具有指令重排的特性,在多线程环境下可能出现 singleton 已经赋值但还没初始化的情况,导致一个线程获得还没有初始化的实例。
* volatile 关键字的作用
* 1.保证了不同线程对这个变量进行操作时的可见性
* 2.禁止进行指令重排序
*/
private static volatile Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
双重检查锁总结
优点: 线程安全 延迟加载 效率较高
四.静态内部类方式
/**
* 静态内部类写法 线程安全
* @Author: zxs
* @Date: 2019/8/26
*/
public class Singleton {
private Singleton() {
}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
静态内部类总结
利用了类加载机制实现线程安全.当 Singleton.getInstance() 调用时候 才会实例化,不会造成内存空间浪费。
五.枚举方式
enum Singleton {
INSTANCE;
public void anyMethod(){}
}
网友评论