加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 这个单例模式线程安全吗?

发布时间:2020-12-15 05:12:17 所属栏目:Java 来源:网络整理
导读:我有一个单例服务器实例,我很好奇我的代码是否是线程安全的. I’ve read关于不同的单例模式,我认为通常的方法是双重检查锁定模式,如下所示: public static Singleton getInstance() { if(singleton == null) { synchronized(Singleton.class) { if(singleto
我有一个单例服务器实例,我很好奇我的代码是否是线程安全的. I’ve read关于不同的单例模式,我认为通常的方法是双重检查锁定模式,如下所示:

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

这被认为是设置/获取单身的有效线程安全方式.我读过,获取和设置单例的最简单方法是延迟实例化,如下所示:

public static ClassicSingleton getInstance() {
    if(instance == null) {
        instance = new ClassicSingleton();
     }
     return instance;
}

现在我想知道的是我的变体是否是线程安全的.我的代码:

public static void startServer(int listeningPortNumber) throws IOException {
    if (server != null) {
        throw new IOException("Connection exists");
    }

    server = new Server(listeningPortNumber);
}

我的代码与上面的惰性实例化模式非常相似,但我看不出我的代码是如何不是线程安全的.有没有我没看到的东西,或者这是真正有效的代码?

参考:http://www.javaworld.com/article/2073352/core-java/simply-singleton.html

解决方法

这不安全.

想象一下如果两个线程同时调用startServer(或者足够接近它)会发生什么:

>线程A检查服务器!= null,并看到该服务器为空 – 因此它不会引发异常
>线程B也是如此
>线程A现在实例化新的服务器(listeningPortNumber);
>线程B做同样的事情,并且可能在第二次实例化时发生了不好的事情

如果服务器不是易失性的,问题就更糟了,因为你甚至不再需要交错 – 线程A可能实例化新的服务器(…),但写入服务器字段是’线程B看了很长时间(可能永远),因为它没有刷新到主存储器.

但是,即使服务器是易失性的,由于交错,该方法也很有效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读