单例模式

单例模式

 饿汉式

由于对象在类里面才能被创建,而且是静态的,所以,被创建的对象始终都是一个,由于在类装载时就被完成了实例化,所以没有线程安全问题,如果没有使用这个实例,会造成内存浪费

//饿汉式
class Singleton1{
    public String name;
    private static final Singleton1 instance = new Singleton1();
    private Singleton1(){
        System.out.println("Singleton1,被构建对象");
    }
    public static Singleton1 getInstance(){
        return instance;
    }
}

懒汉式

线程不安全

起到了懒加载效果,但是只能在单线程使用,多线程会不安全,因为当多个线程并发同时判断instance为空时,就会相应的实例化多个对象。

class Singleton { //线程不安全
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {  //调用时才实例化对象,懒汉式
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

以线程安全的方式创建

上面线程不安全,那上锁不就好了,使用synchronized关键字。 这样虽然解决了线程安全,但其实实例化操作只做一次,而获取实例(即getInstance)的操作是很多次的,把调用的方法加上同步,会大大降低效率。

复制代码
class Singleton { //线程安全
    private static Singleton instance;
    private Singleton() {}
    //synchronized同步处理
    public static synchronized Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
复制代码
复制代码
class Singleton { //双重检查
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if(instance == null) { //判断是否实例化
            synchronized (Singleton.class) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance; //否则直接return
    }
}
复制代码
复制代码
class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    //静态内部类,包含一个静态属性:Singleton
    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton(); 
    }
    //对外公有的静态方法,直接返回SingletonInstance.INSTANCE
    public static synchronized Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}
复制代码

使用枚举也可以完成单例模式

复制代码
enum Singleton {
    INSTANCE; //属性
    public void say() {
        System.out.println("记得三连~");
    }
}
复制代码
复制代码
public static void main(String[] args) {
        Singleton instance1 = Singleton.INSTANCE;
        Singleton instance2 = Singleton.INSTANCE;
        System.out.println(instance1 == instance2);
    
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
        
        instance1.say();
    }
复制代码

测试结果

  • true
  • 460141958
  • 460141958
  • happy!

.

posted @ 2022-10-24 14:07  happy_in  阅读(23)  评论(0)    收藏  举报