线程中的单例模式(懒汉和饿汉)

单例模式中的单例指的就是单个实例对象。在一个程序中,某个类只能创建出一个实例(对象),不能创建多个对象

java中实现单例模式有很多种写法,在这里我们只介绍两种,饿汉模式和懒汉模式。

饿汉模式可以简单的理解为,一上来就创建好这个实例。代码如下:

package threrading;
//把这个类设定成单例的
class Singleton{
        //饿汉模式

    //唯一实例的本体,一开始就创建好了,要用即可拿
    private static Singleton instance = new Singleton();

    //获取到实例的方法
    public static Singleton getInstance() {
        return instance;
    }

    //禁止外部new实例
    private Singleton(){ }

}

public class ThreadDemo16 {
    public static void main(String[] args) {
        //此时s1和s2是同一个实例
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();

        //Singleton s3 = new Singleton();
    }
}

懒汉模式简单的理解就是非必要不创建,当需要的时候才创建,代码如下:

package threrading;

//通过懒汉模式实现单例模式(非必要不创建)
class SingletonLazy {
	//定义实例对象,初始化为Null
    volatile private static SingletonLazy instance = null;

    public static SingletonLazy getInstance(){
        //这个条件判定是否要加锁,如果有对象了,此时不用加锁,线程本身就是安全的
        //虽然下面两个if条件相同,但是如果调用时间间隔太长了,结果也有可能不同
        if(instance==null){
            //保证判定和new是一个原子操作
            synchronized (SingletonLazy.class){
                if(instance==null){
                    instance = new SingletonLazy();
                }
            }
        }
        //如果不为空,之间返回实例
        return instance;
    }
    
    private SingletonLazy(){}
    
    /**
     * 1.加锁,把if和New变成原子操作
     * 2.双重if,减少不必要的加锁操作
     * 3.使用volatile禁止指令重排序,保证后续线程肯定拿到的是完整对象
     */
}

        //认为饿汉模式是线程安全的,懒汉模式不是,因为前者只是读数据
        //多线程下,懒汉模式可能无法保证创建对象的唯一性
public class ThreadDemo17 {
    public static void main(String[] args) {
        SingletonLazy s1 = SingletonLazy.getInstance();  //在使用的时候才会创建实例
        SingletonLazy s2 = SingletonLazy.getInstance();
        System.out.println(s1==s2);
    }
}

你可能感兴趣的:(JavaEE,单例模式,java,开发语言,javaee,安全)