哪一个是更好的单身人士,为什么?

时间:2014-02-20 04:16:31

标签: java

我在接受采访时被要求检查以下两种宣布单身人士课程的方式中哪一种更合理。有人可以分享一些想法

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

OR

public static synchronized Singleton getSingleInstance() {
    if (singleInstance == null) {
        singleInstance = new Singleton();
    }
    return singleInstance;
}

3 个答案:

答案 0 :(得分:0)

由于这是一个面试问题,我认为他们的意图是#1,因为它避免了大部分时间的同步。

答案 1 :(得分:0)

答案取决于什么更重要,性能或代码易读性。对于性能,第一个更好[2],但为了易读性,第二个更好,因为更少的代码行更容易理解和证明没有错误。

[2]假设该方法被多次调用,性能将取决于与定义单例方法的类上的监视器相比的易失性读取的速度。我没有任何定量证据,但我认为前者更好。

对于它的价值,Apache公共LazyInitializer使用第一个(http://commons.apache.org/proper/commons-lang/apidocs/src-html/org/apache/commons/lang3/concurrent/LazyInitializer.html):

@Override
public T get() throws ConcurrentException {
    // use a temporary variable to reduce the number of reads of the
    // volatile field
    T result = object;

    if (result == null) {
        synchronized (this) {
            result = object;
            if (result == null) {
                object = result = initialize();
            }
        }
    }

    return result;
}

答案 2 :(得分:0)

完全取决于您的需求。

在这种情况下 - 问题之外的第一个问题是没有正确保护测试(你的if应该在同步中,或者你冒着竞争条件,其他人在你测试之后但在你之前改变了它)已经完成了对测试结果的处理),所以你可以结束两个实例 - 这两个实例在JIT完成之后可能是相同的。

但是,一般情况下,同步方法的问题往往是它们过度同步。他们中的许多人保持锁定的时间超过绝对必要的时间,并且可能通过迫使其他线程等待更长时间来降低性能。同步应该在使操作成为原子所需的最短时间内完成,并且通常可以限制为几个关键线而不是整个方法。

另一方面......有时候最好不要让班级线程安全。哈希表是线程安全的; HashMaps(较新的替代品)不是。这是因为获取锁是一个相对昂贵的过程,特别是在多处理器环境中,并且在现实世界的代码中,如果需要线程安全,它通常希望覆盖的不仅仅是单个hashmap访问,因此在这个级别锁定通常是浪费而不是有用。 / p>