java – 这个单例模式线程安全吗?
我有一个单例服务器实例,我很好奇我的代码是否是线程安全的.
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,并看到该服务器为空 – 因此它不会引发异常 如果服务器不是易失性的,问题就更糟了,因为你甚至不再需要交错 – 线程A可能实例化新的服务器(…),但写入服务器字段是’线程B看了很长时间(可能永远),因为它没有刷新到主存储器. 但是,即使服务器是易失性的,由于交错,该方法也很有效. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |