我亦无他,唯手熟尔!
多线程下的单例设计模式
众所周知,单例模式中,构造方法是私有化的,通过静态方法内部调用构造函数返回该类的实例对象。常见的代码如下所示:
1
2
3
4
5
6
7
8
9
10
|
public Singleton { private static Singleton singletonObj; private Singleton(){} public static Singleton getInstance(){ if (singletonObj == null ){ singletonObj = new Singleton(); } return singletonObj; } } |
在单线程的情况下,确实可以保证只有一个实例,但是在多线程的情况下,就会发生意想不到的情况。
创建一个TestSingleton类,如下:
public TestSingleton implements Runnable { private Singleton s = null ; public Singleton getS() { return s; } public void setS(Singleton s) { this .s = s; } public static void
TestSingleton ts1 = new TestSingleton(); TestSingleton ts2 = new TestSingleton(); Thread t1 = new Thread(ts1); Thread t2 = new Thread(ts2); t1.start(); t2.start(); Singleton s1 = ts1.getS(); Singleton s2 = ts2.getS(); System.out.println(s1 == s2); } @Override public void run() { s = Singleton.getInstance(); } } |
运行结果返回 false
在多线程的环境中需要考虑同步的问题,对上述单例模式的代码进行修改,如下:
public Singleton getInstance() { if (singletonObj == null ) { synchronized (Singleton. class ) { if (singletonObj == null ) { singletonObj = new Singleton(); } } } return singletonObj; } |
重新运行上述TestSingleton ,返回结果 true 此时,保证即使是在多线程的环境下,依然能够保持单例模式的正确性。