单例模式多线程问题

publicclassSingleton{privatestaticSingletonsingle;privateSingleton(){}privateintcount... public class Singleton{
private static Singleton single;
private Singleton(){}
private int count = 0;
public static Singleton getInstance(){
if(single == null){
synchronized(Singleton.class){
if(single == null){
try{
Thread.sleep(1000);
}catch(Exception e){}
single = new Singleton();
}
}
}
return single;
}
public void printCount(){
System.out.println(count++);
}
}
public class MultiThread extends Thread {
public static void main(String[] args) {
for(int i = 0; i < 100; i++){
MultiThread thread = new MultiThread();
thread.start();
}
}
public void run() {
Singleton single = Singleton.getInstance();
single.printCount();
}
}
结果如下:

运行一次可能会正常输出1到99,多运行几次就会出现类似上图情况,输出了两个37,为什么会出现这种情况?上面的单例模式应该是线程安全的吧?
展开
 我来答
空雪梦见
2014-09-19 · TA获得超过5598个赞
知道大有可为答主
回答量:2522
采纳率:75%
帮助的人:1212万
展开全部
单例模式不自带线程安全的功能。你上面的getInstance只是在创建的时候能够防止创建出两个实例。
printCount不是线程安全的
追问
多个线程访问的是一个实例对象,同一个对象的方法执行应该有先后顺序吧。就像一个打印机一样,多个人想去打印东西,但是只有一个打印机,不是按顺序访问的吗?你能解释下在虚拟机以及内存分配这段代码是如何执行的吗?
追答
不是先后。在创建对象的时候因为有锁,所以有先后:两个线程不能同时执行到new那边。但是在count++那里情况不同,你没有锁,两个线程可以同时在count++上面执行。
打印机的顺序访问是由操作系统来保证的,操作系统来维护队列、来向打印机发送请求。而你现在并没有这样一个系统来保证对count的访问是顺序的。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式