初识单例模式
Posted 无赖H4
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识单例模式相关的知识,希望对你有一定的参考价值。
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
作为单例模式:
1、只能实例化一个对象——把构造方法私有化
2、只需要一个引用,保存唯一的那个对象——静态属性保存
3、别人要使用这个类对象,返回这个引用指向的对象即可——静态方法返回。
饿汉模式
作为饿汉模式,一开始就实例化好对象等待调用。
class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
饿汉模式:线程安全:实例对象发生在静态初始化(类加载)
JVM规定:进行类加载的时候,只会有一个线程在操作
懒汉模式
懒汉模式:延迟加载-懒加载(Lazy Load)-按需加载
懒汉模式:把对象的实例化放在第一次调用的时候。
单线程版
class Singleton {
private static Singleton instance = null;
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
}
private Singleton(){
}
}
如果在单线程的情况下,上述写法是可以的,但是在多线程情况下,是线程不安全的是典型的check-update写法
破坏了原子性。
多线程版-性能低
1、破坏了原子性,我们可以通过加锁操作解决
class Singleton {
private static Singleton instance = null;
private Singleton(){
}
public synchronized static Singleton getInstance(){
if(instance == null){
return new Singleton();
}
return instance;
}
}
这种情况保证了线程安全,但是效率不高
在保护原子性中的 instance = new Singleton 只需要在一开始,但是会在整个生命周期中承受加锁保护,会造成性能损耗。
多线程版-性能高
class Singleton {
private static volatile Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
1、需要二次判断:因为从开始加锁,到加锁成功,可能经过了很久,加入两个线程同时到达,可能new两个对象
2、volatile在此处的目的是:为了保证new Singleton();的代码重排序问题。
如果没有volatile关键字,instance 在有一段时间内会指向一个没有被正确初始化的对象(引用不为空),调用getInstance方法会出现错误的结果。
以上是关于初识单例模式的主要内容,如果未能解决你的问题,请参考以下文章