请选择 进入手机版 | 继续访问电脑版
本站特色:极好的技术研究氛围!所有技术交流,必有回复!

疯狂Java联盟

 找回密码
 加入联盟
查看: 369|回复: 5

关于双if判断的懒汉式单例的问题

[复制链接]
发表于 2018-4-10 18:21:57 | 显示全部楼层 |阅读模式
代码如下

new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000; i++) {
                    instance1 = SingletonSy.getInstance();

                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    instance2 = SingletonSy.getInstance();
                }
            }
        }).start();

        Log.i(TAG, String.valueOf(instance1 == instance2));





public class SingletonSy {

    private volatile static SingletonSy singletonSy=null;

    private SingletonSy() {

    }

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


但是打印的值却是这样的

04-10 10:19:30.800 16533-16533/com.example.handler.myapplication I/MainActivity: true
04-10 10:19:34.271 16606-16606/com.example.handler.myapplication I/MainActivity: true
04-10 10:19:37.374 16683-16683/? I/MainActivity: false
04-10 10:19:42.183 16759-16759/com.example.handler.myapplication I/MainActivity: true
04-10 10:19:46.070 16837-16837/com.example.handler.myapplication I/MainActivity: true
04-10 10:19:49.416 16914-16914/com.example.handler.myapplication I/MainActivity: true
04-10 10:19:52.815 16990-16990/com.example.handler.myapplication I/MainActivity: false


这就说明,并发问题,并未解决。。。
 楼主| 发表于 2018-4-10 18:33:49 | 显示全部楼层
饿汗和懒汉好像在这种多线程的情况都会出现并发
 楼主| 发表于 2018-4-11 09:58:40 | 显示全部楼层
其实这for循环是没必要写的。。。最终只是一个对象而已。。。
 楼主| 发表于 2018-4-11 10:34:24 | 显示全部楼层
demo写的有问题,打印地址值才知道,有一些会是null,但是还是不太懂。。
 楼主| 发表于 2018-4-11 11:12:46 | 显示全部楼层
写的demo有问题。。并不太能验证。。多线程常识。。。
解释起来就是 CPU调度。。唉。难的要死
发表于 2018-4-14 03:21:40 | 显示全部楼层
这个出现false是非常平常的的事情,是一个很基础的多线程问题。
主线程中创建并启动了2条线程、加上主线程共有3条线程。
A线程,负责创建instance1,
B线程,负责创建instance2,
主线程,负责创建、并启动A、B线程,并比较instance1和instance2,

A、B、主线程是并发,并发就意味着它们没有先后顺序。这意味着当主线程执行到
Log.i(TAG, String.valueOf(instance1 == instance2));代码时,A、B线程完全可能还没有完成instance1、instance2的赋值,只要它们之间任意一个没有完成赋值,程序自然就输出false。

为了验证我的话,你可以把Log.i(TAG, String.valueOf(instance1 == instance2));改为如下形式:
  1. if( instance1 != null && instance2 != null)
  2. {
  3.         System.out.println(instance1 == instance2);
  4. }
复制代码

你就会发现,上面代码经常不会产生输出,这说明instance1、instance2至少有一个还没有赋值。
您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

小黑屋|手机版|Archiver|疯狂Java联盟 ( 粤ICP备11094030号 )

GMT+8, 2018-10-21 03:32 , Processed in 0.285349 second(s), 6 queries , File On.

快速回复 返回顶部 返回列表