May 30, 2021 Article blog
1. What is a single-case pattern?
2. The pros and cons of a single-case pattern
3. The implementation of a single-case pattern
merit
shortcoming
/**
*Singleton类,单例模式类,在类加载时便会创建一个私有静态变量instance,也就是该类的实
*例,再通过公共接口getInstance()来发布该实例
*/
public class Singleton {
private static Singleton instance;
//私有化构造方法防止外界new对象
private Singleton (){
}
//公有化静态函数,对外暴露单例对象的接口
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
However, this approach does not guarantee that this is the only single case, in high concurrent access, multiple threads access to this single case at the same time, there is still no guarantee that this class is a single case
In order to ensure thread safety, we can add a lock, to this getInstance() method plus thread synchronization lock synchronize implementation as follows:
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
However, once locked, although can guarantee that in fact a single case and thread-safe, but in high concurrent access performance must be affected, multiple threads need to use the single case, can not guarantee speed, need to wait synchronously for this single case to use back to the JVM heap (Heap) can continue to use this single case, the efficiency is very low.
There is also a double check, two judgments
Double Check Lock (DCL) implements a single-case pattern
public class Singleton{
private volatile static Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
We can see that the instance has been judged twice in gettance is empty, the first judgment is mainly to avoid unnecessary synchronization problems, the second judgment is to create instances in the case of null, because in some cases there will be failure problems, namely DCL failure problems, you can use the vollatile keyword to deal with this problem, but the same, the use of volateile keywords will also have some impact on performance. However, the advantage is that the resource utilization is high, the object is instantiated the first time the getInstance is executed, but the DCL also because the first load response is slow, so in the case of high concurrence will also have some defects.
/**
*这种方式在类加载时就完成了初始化,所以类加载较慢,但是获取对象的速度快。这种方式
*基于类加载机制,避免了多线程的同步问题。如果从来没有使用过这个实例,则会造成内存
*的浪费。
*/
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
Anonymous internal class/static inner class
public class Singleton {
private static Singleton instance;
//静态块在类加载时会被执行,也就创建了Singleton类实例
static{
instance = new Singleton();
}
private Singleton (){
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
/**
*Java静态内部类的特性是,加载的时候不会加载内部静态类,使用的时候才会进行加载。
*第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚
*拟机加载SingletonHolder并初始化sInstance。这样不仅能确保线程安全,也能保证
*Singleton类的唯一性。所以,推荐使用静态内部类单例模式
*/
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
/**
*默认枚举实例的创建是线程安全的,并且在任何情况下都是单例。
*枚举单例的有点就是简单,缺点是可读性不高。
*/
public enum Singleton {
//外部调用由原来的Singleton.getInstance变成了Singleton.INSTANCE了。
INSTANCE;
}
Single-case mode is a pattern that uses a high frequency, and in our clients there is usually no high concurring situation, so choosing which method does not have much impact. For efficiency reasons, it is recommended to use a single-case pattern for static internal classes and a single-case pattern for DCL.
merit:
shortcoming:
Recommended good lessons: Java: 23 days zero foundation fully introductory, Java interview basic questions should be informed