多核处理器中的单例

时间:2014-12-10 12:06:01

标签: java multithreading singleton

一位采访者问我这个问题,我对此感到困惑。

问题是:在您实施单例DP的webapp中,您将其托管在四核处理器中。这意味着4个核心/线程。当一个请求来自用户时,一个线程将服务,当另一个请求命中服务器时,下一个线程将尝试服务。

因此,在这种情况下,如何在核心/线程之间共享单个对象。

他们会等待第一个完成吗?或其他什么?

6 个答案:

答案 0 :(得分:3)

提供,Singleton对象是线程安全的,每个JVM只会创建一个单独的对象。此外,如果单个对象由多个线程共享,并且每个线程调用特定方法,则每个方法调用将独立于其他线程执行。当然,如果该方法正在操纵某些共享属性,则会出现问题。在这种情况下,您需要同步对单例方法的访问。

答案 1 :(得分:1)

如果单例实现不是线程安全的,那么线程可能会创建两个或更多实例。在实现设计模式时,您必须确保它的线程安全。

执行此操作的最佳方法之一是使用按需初始化持有者惯用法,因为它滥用了JVM在加载类时的工作方式。

public class Something {
    private Something() {}

    private static class LazyHolder {
        private static final Something INSTANCE = new Something();
    }

    public static Something getInstance() {
        return LazyHolder.INSTANCE;
    }
}

更通用的解决方案是自己synchronize,但它比以前的解决方案效率低,因为你必须使用双if条件。

public class ASingleton {

    private static ASingleton instance = null;
    private static Object mutex = new Object();

    private ASingleton() {
    }

    public static ASingleton getInstance() {
        if (instance == null) {
            synchronized (mutex) {
                if (instance == null)
                    instance = new ASingleton();
            }
        }
        return instance;
    }
}

答案 2 :(得分:1)

Singleton模式意味着每个JVM有一个实例。这意味着线程或处理器的数量无关紧要 - Java虚拟机中只有一个实例(即正在运行的进程)。

当然,这确实假设您遵循一个正确的模式来创建单例,例如将其分配给静态的最终类属性,以便在类加载器加载类时加载它。如果您严重初始化它可能会创建多个实例,但这仍然不受核心/处理器数量的影响。

答案 3 :(得分:1)

根据定义,单身人士不是线程安全的。如果单例需要是线程安全的,则在从不同的线程访问它时必须使用同步。除此之外,java线程和OS线程之间存在差异。单线程Java应用程序可能受益于多线程操作系统(例如更好的性能),多线程Java应用程序可以在单线程操作系统上运行(例如,通过交替分配CPU周期到不同的线程)。

答案 4 :(得分:1)

两个线程将并行执行相同的代码(这与对象是否是单例无关)并共享相同的内存(这是单例出现的位置)。

代码中的同步可能会改变实际指令在不同时间执行控制线程是否被阻止的方式,但这实际上是次要问题而不是我认为面试官要求的内容。

答案 5 :(得分:0)

  

他们会等待第一个完成吗?

这取决于实现。

由于同步机制,此单例只能一次调用一次:

public enum Singleton {
    INSTANCE;
    public synchronized int method() { return 1; }
}

可以通过任意多个线程同时调用此单例(限制是您的硬件):

public enum Singleton {
    INSTANCE;
    public int method() { return 1; }
}