多线程 单例模式之懒汉

/**
 * 1. 懒汉(延迟加载)
 * 2. 正确
 * 3. 效率还比较高
 * 通过
 * 1. volatile 的引入,目的解决 ins = new ...(); 重排序带来的问题
 * 2. synchronized 的引入,目的是解决原子性问题
 * 3. 见方法注释
 */
public class LazySingleton3 {
//直属类的对象
    private static volatile LazySingleton3 ins = null;
 //构造方法
    private LazySingleton3() {}
   //一个获得  ins 的方法 
    public static LazySingleton3 getInstance3() {
        if (ins == null) {
            synchronized (LazySingleton3.class) {
                if (ins == null) {
                    ins = new LazySingleton3(); 
                }
            }
        }

        return ins;
    }
 //建立一个线程的类
    static class MyThread extends Thread {
        @Override
        public void run() {
            LazySingleton3 ins1 = LazySingleton3.getInstance3();
            System.out.println(ins1);
        }
    }
//将这个程序以多线程运行
    public static void main(String[] args) {
        MyThread[] threads = new MyThread[20];
        for (int i = 0; i < 20; i++) {
            threads[i] = new MyThread();
        }
        for (int i = 0; i < 20; i++) {
            threads[i].start();
        }
        /*
        单例模式之懒汉1 ins1 = 单例模式之懒汉1.getInstance();
        单例模式之懒汉1 ins2 = 单例模式之懒汉1.getInstance();
        单例模式之懒汉1 ins3 = 单例模式之懒汉1.getInstance();

        System.out.println(ins1 == ins2);
        System.out.println(ins2 == ins3);
        */
    }
}

懒汉の单例模式:
单例:只实例化一个对象。

与饿汉的开局就初始化不同,懒汉只是在有线程调用它时才会初始化对象,此举目的为节省内存空间。

若无synchronized 则会存在原子性不能保证的问题,可能会new出多个对象,不符合单例的情况。
若无外边的if(ins==null),那么会导致整个代码效率变低,因为在第一次new对象后,这个锁依旧会被互斥线程抢。
若无全局变量 ins 前的volatile,那么ins这个对象内部的(开辟空间,初始化,给引用赋值)三个大步骤会有重排序的问题。

发布了15 篇原创文章 · 获赞 0 · 访问量 261

猜你喜欢

转载自blog.csdn.net/rushrush1/article/details/104849828