Java 单例模式,Java Singleton单例模式

Java 单例模式,Java Singleton单例模式

 

================================

©Copyright 蕃薯耀 2021-04-14

https://www.cnblogs.com/fanshuyao/

 

一、单例模式 - 饿汉模式

* 单例模式-饿汉模式
* 优化:代码简单,线程安全
* 缺点:类初始化时,直接创建了对象,增加了内存的使用

/**
 * 单例模式-饿汉模式
 * 优化:代码简单,线程安全
 * 缺点:类初始化时,直接创建了对象,增加了内存的使用
 *
 */
public class SingletonHungry {

    /**
     * 创建对象,使用static final修饰
     */
    private static final SingletonHungry singletonHungry = new SingletonHungry();
    
    /**
     * 私有化(private)无参数的构造方法,不会被外部类创建对象
     */
    private SingletonHungry() {}
    
    /**
     * 返回单例对象的方法
     * @return
     */
    public static SingletonHungry getInstance() {
        return singletonHungry;
    }
    
    
}

 

单例模式-饿汉模式测试代码:

public class Main {
    
    public static void singletonHungry() {
        for(int i=0; i<15; i++){
            new Thread(()-> {
                System.out.println(SingletonHungry.getInstance() == SingletonHungry.getInstance());
            }).start(); 
        }
    }
    
    public static void main(String[] args) {
        singletonHungry();
        
    }

}

 

二、单例模式 - 懒汉模式 - 双重判断

* 单例模式-懒汉模式
* 优点:性能好,不直接创建对象,需要时才创建
* 缺点:双重判断,代码复杂

/**
 * 单例模式-懒汉模式
 * 优点:性能好,不直接创建对象,需要时才创建
 * 缺点:双重判断,代码复杂
 *
 */
public class SingletonLazy {

    /**
     * 声明对象,使用static,不使用final修饰,要使用volatile修饰,volatile避免指令重排序的问题
     */
    private static volatile SingletonLazy singletonLazy;
    
    /**
     * 私有化(private)无参数的构造方法,不会被外部类创建对象
     */
    private SingletonLazy() {}
    
    
    /**
     * 返回单例对象的方法
     * 双重判断
     * 在创建对象时加synchronized关键字修饰,不是整个方法,性能更加好
     * 
     * @return
     */
    public static SingletonLazy getInstance() {
        
        if(singletonLazy == null) {
            synchronized (SingletonLazy.class) {
                if(singletonLazy == null) {
                    singletonLazy = new SingletonLazy();
                }
            }
        }
        return singletonLazy;
    }
}

 

测试代码:

public class Main {

    public static void singletonLazy() {
        for(int i=0; i<15; i++){
            new Thread(()-> {
                System.out.println(SingletonLazy.getInstance() == SingletonLazy.getInstance());
            }).start();
        }
    }
    

    public static void main(String[] args) {
        singletonLazy();
    }

}

 

存在问题:

如果不使用双重判断和synchronized关键字修饰,会出问题:

    public static SingletonLazy getInstance() {
        
        if(singletonLazy == null) {
            singletonLazy = new SingletonLazy();
        }
        
        return singletonLazy;
    }

 

测试结果:存在 false

true
true
true
true
true
true
true
true
true
false
true
true
true
true
true

 

如下图所示:

 

 

(时间宝贵,分享不易,捐赠回馈,^_^)

================================

©Copyright 蕃薯耀 2021-04-14

https://www.cnblogs.com/fanshuyao/

posted @ 2021-04-14 10:46  蕃薯耀  阅读(74)  评论(1编辑  收藏  举报