有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么在这个多线程应用程序中需要单例模式?

我最近有a problem with two threads sticking in deadlock because they weren't monitoring the same object the way I thought they were。事实证明,实现单例模式solved the problem<但是为什么呢

我只实例化了类的一个实例,该类的对象是私有属性,所以我希望它实际上是单例的


为了问题的完整性,这里还有一些代码来说明区别:

在实施单例模式之前:

class Worker {
    private BlockingQueue q = new LinkedBlockingQueue();

    public void consume(String s) {
        // Called by thread 1.
        // Waits until there is anything in the queue, then consumes it
    }

    public void produce(String s) {
        // Called by thread 2.
        // Puts an object in the queue.
    }

    // Actually implements Runnable, so there's a run() method here too...
}

线程是这样开始的:

Worker w = new Worker();
new Thread(w).start();

// Producer also implements Runnable. It calls produce on its worker.
Producer p = new Producer(w);
new Thread(p).start();

现在,当我检查produce()consume()中实际使用的队列时,System.identityHashCode(q)在不同的线程中给出了不同的结果

对于单例模式:

class Worker {
    private static BlockingQueue q;
    private BlockingQueue getQueue() {
        if(q == null) {
            q = new LinkedBlockingQueue();
        }
        return q;
    }
    // The rest is unchanged...
}

突然间,它起了作用。为什么这种模式在这里是必要的


共 (1) 个答案

  1. # 1 楼答案

    根据您发布的伪代码,真正起作用的不是单例模式,而是static的使用。在第一个示例中,队列不是声明为静态的,因此Worker的每个实例都将实例化自己的LinkedBlockingQueue。在第二个示例中声明static时,将在类级别创建队列,并在所有实例之间共享

    根据你在另一个问题中发布的代码,错误就在最后一行:

    public Server(Worker worker) {
            this.clients = new ArrayList<ClientHandle>();
            this.worker = new Worker();
    

    那么你的声明呢

    I only instantiated one instance of the class of which the object was a private property, so I expected it to be effectively singleton anyway.

    这是不准确的。你是在暗示每个新服务器中都有一个新的工作人员,而不是重用传入的工作人员