单例模式

1)饿汉式单例模式

package Singleton;

public class Singleton01 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        System.out.println(instance);

    }
}
class Singleton{
    private Singleton(){

    }
    private final static Singleton instance = new Singleton();
    public static Singleton getInstance(){
        return instance;
    }
}

优点:写法简单,类加载的时候就完成了实例化,避免了线程同步的问题

缺点:在类加载的阶段完成了实例化,如果从始至终一直没有用到,就会造成浪费

2)饿汉式静态代码块写法

package Singleton;

public class Singleton02 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        System.out.println(instance);

    }
}
class Singleton2{
    private Singleton2(){

    }

    private  static Singleton2 instance ;
    static{
        instance = new Singleton2();
    }
    public static Singleton2 getInstance(){
        return instance;
    }
}
View Code

3)懒汉式写法(线程不安全)

优点:起到了Lazy Loading的效果

缺点:线程不安全,实际开发中不推荐使用,有可能破坏单例模式的初衷

package Singleton;

public class Singleton03 {
    public static void main(String[] args) {
        Singleton3 instance = Singleton3.getInstance();
        System.out.println(instance);
    }
}
class Singleton3{
    private static Singleton3 instance;
    private Singleton3(){

    }
    public static Singleton3 getInstance(){
        if(instance==null){
            instance = new Singleton3();
        }
        return instance;
    }


}
View Code

4)懒汉式写法(线程安全)

package Singleton;

public class Singleton03 {
    public static void main(String[] args) {
        Singleton3 instance = Singleton3.getInstance();
        System.out.println(instance);
    }
}
class Singleton3{
    private static Singleton3 instance;
    private Singleton3(){

    }
    public synchronized static Singleton3 getInstance(){
        if(instance==null){
            instance = new Singleton3();
        }
        return instance;
    }


}
View Code

优点:解决了线程不安全的问题

缺点:效率太低了,不推荐使用

5)双重检查

package Singleton;

public class Singleton04 {
    public static void main(String[] args) {
        Singleton4 instance = Singleton4.getInstance();
        System.out.println(instance);
    }
}
class Singleton4{
    private static volatile Singleton4 instance;
    private Singleton4(){

    }
    public static Singleton4 getInstance(){
        if(instance==null){
            synchronized (Singleton4.class){
                if(instance==null){
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }
}
View Code

优点:

  有了volatile关键字,就可以保证线程安全

  实例化代码只有一次,避免违背单例模式

  延迟加载,效率较高

  在实际开发中,推荐使用这种单例设计模式

 6)静态内部类

为什么使用静态内部类:当类被加载的时候,静态内部类里面,是不会被装载的

package Singleton;

//利用静态内部类进行初始化
public class Singleton05 {
    public static void main(String[] args) {
        Singleton4 instance = Singleton4.getInstance();
        System.out.println(instance);
    }
}

class Singleton5{
    private static volatile Singleton instance;
    private Singleton5(){}
    private static class Singleton5Instance{
        private static final Singleton5 INSTANCE = new Singleton5();
    }
    public static synchronized Singleton5 getInstance(){
        return Singleton5Instance.INSTANCE;
    }
}
View Code

优点:

  这种方式采用了类加载的机制来保证初始化实例时只有一个线程

  静态内部类在Singleton类被加载时,不会被立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance,从而完成Singleton的实例化

  类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的

  优点:避免了线程不安全的问题,利用静态内部类特点实现延迟加载,效率高

  推荐使用!

posted @ 2021-09-19 15:18  古比  阅读(33)  评论(0编辑  收藏  举报