在Singleton Pattern中,当两个或多个线程同时执行时会发生什么?

时间:2019-01-17 05:35:56

标签: java design-patterns singleton

在下面,我试图以单例模式发送两个线程,以查看两个线程如何工作而不进行同步。理论上,两个线程应创建两个单独的对象。但是在这里,如果不进行同步,则仅创建一个对象,并且创建两个对象的详细信息线程正在分配两个对象。打印对象时可以看到它。这是怎么回事。为什么不创建两个对象?

public class Singleton_Pattern {

    public static void main(String[] args) {
     Test1 t1=new Test1();
     t1.start();
     Test2 t2=new Test2();
     t2.start();
     t1.m();
     t2.m();
    }
}

class Test1 extends Thread {

    void m() {
        System.out.println(A.getA());
        A.getA().setValue("Cat");
        System.out.println(A.getA().getValue());
    }
}

class Test2 extends Thread {

    void m() {
        System.out.println(A.getA());
        A.getA().setValue("Dog");
        System.out.println(A.getA().getValue());
    }
}

class A {

    private static A a;
    String name;

    private A() {

    }

    public static A getA() {
        if (a == null) {

            a = new A();
        }
        return a;
    }

    public void setValue(String t) {
        name = t;
    }

    public String getValue() {
        return name;
    }
}

2 个答案:

答案 0 :(得分:0)

您为什么认为从不同的线程调用getA()应该创建不同的对象?一个应用程序只有一个static区域。因此,在这种情况下,两个线程都应使用相同的对象。

在您的示例中,您正在使用主线程调用m()方法。您应该重写run()方法以有效使用多个线程。在您的Test1Test2类中添加以下方法。

public void run() {
   m();
}

并从您的main方法中删除以下行,

t1.m();
t2.m();

答案 1 :(得分:0)

您正在主线程上调用m()。要在单独的线程中调用它,您需要在线程类中重写run()方法,并从m()内部调用run()

修复此问题后,两个线程完全同时进入该块(最短为纳秒)是非常不可能的。您可以尝试使用多个线程和运行循环来查看并发问题。但是由于a是静态的,因此“新”对象将迅速覆盖旧实例。

看看this answer来了解单例模式中的同步。