单例模式线程安全性问题的分析

饿汉式

public class Singleton {
    // 私有化构造方法
    private Singleton() {}

    private static Singleton s = new Singleton();

    public static Singleton getInstance() {
        return s;
    }
}

无线程安全问题

懒汉式

public class Singleton {
    // 私有化构造方法
    private Singleton() {}

    private static Singleton s = null;

    public static Singleton getInstance() {
        if (s == null) {
            s = new Singleton();
        }
        return s;
    }
}

获取单例的时候不是原子操作,所以有线程安全性问题。

解决方案-加synchronized

public class Singleton {
    // 私有化构造方法
    private Singleton() {}

    private static Singleton s = null;

    public static synchronized Singleton getInstance() {
        if (s == null) {
            s = new Singleton();
        }
        return s;
    }
}

缺点:多个线程相当于一个个执行,性能太差

解决方案-双重检查加锁


public class Singleton {
    // 私有化构造方法
    private Singleton() {}

    private static Singleton s = null;

    public static synchronized Singleton getInstance() {
        if (s == null) {
            synchronized (Singleton.class) {
                if (s == null) {
                    s = new Singleton();
                }
            }
        }
        return s;
    }
}

缺点:指令重排序仍然有可能导致线程安全问题。

解决方案-双重检查加锁改进

public class Singleton {
    // 私有化构造方法
    private Singleton() {}

    private static volatile Singleton s = null;

    public static synchronized Singleton getInstance() {
        if (s == null) {
            synchronized (Singleton.class) {
                if (s == null) {
                    s = new Singleton();
                }
            }
        }
        return s;
    }
}

给变量加锁volatile可避免指令重排的问题

猜你喜欢

转载自blog.csdn.net/qqqq0199181/article/details/80992095
今日推荐