java关于HashSet的一点疑惑,请大神指点一下~~

 我在一个单例模式的测试中,把get到的对象放在HashSet中,利用Set集合的去重,来观察究竟生成的是否为一个实例,但结果却让我很不解,求大家指点,先把代码贴出来。

Singleton.java:

 package test;

public class Singleton {

    private static Singleton instance = null;
    // 记录执行了几次new Singleton
    private static int count = 0;

    private Singleton() {
        count++;
    }

    public static int getCount() {
        return count;
    }

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

Test.java:

 package test;

import java.util.HashSet;
import java.util.Set;

public class Test {

    //创建HashSet结合
    private static Set<Singleton> set = new HashSet<Singleton>();

    public static void main(String[] args) {

        //创建实现Runnable接口的对象
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Singleton instance = Singleton.getInstance();
                set.add(instance);
            }
        };

        //循环启动线程10000次
        for (int i = 0; i < 10000; i++) {
            new Thread(runnable).start();
        }

        //输出结果
        System.out.println("set.size() == " + set.size());
        System.out.println("set contains : " + set);
        System.out.println("Singleton.count == " + Singleton.getCount());

    }
}

输出结果很奇怪,

每次执行main方法后,输出的set.size()值都是不固定的,基本在1-5之内随机。

但直接控制台输出 set ,里边看到只有一个对象。

Singleton.getCount()方法的输出也永远是1。

不明白为什么第一个输出set.size是什么情况。

结果贴图出来:
执行结果

 public

多线程环境下,这么写单例模式是有问题的(问题并非发生在代码层次而是jvm层次)。
在Singleton的构造器里加Sleep拖慢构造速度有一定概率能造出以下情况:
图片说明
参考:Java多线程编程环境中单例模式的实现 (内部类实现多线程环境中的单例模式)

改成线程安全的就行了
private static Set set = Collections.synchronizedSet(new HashSet());