Singleton 模式在多线程实现下的误区

今天使用多线程的方式写一个程序。非常不幸,碰到了死锁问题,最终发现:单例对象的创建时必须保证是同步的,否则多线程高并发情况下,可能创建出多个对象。并且导致错误。
以前写单例对象时使用的是下面的错误的写法:

public static SomeObject getInstance()
{
    if (instance == null)
    instance = new SomeObject();
    return instance;
}

于是在多线程高并发的情况下,public static SomeObject getInstance()方法由于没有同步,被两个线程同时进入,这时候 instance 被创建两次。虽然最终instance对象只会保持有一个(因为只有一个对象句柄),但在这两个对象创建到销毁的一小段时间里边,就有可能发生死锁这样的情况。

所以一定要注意,创建Singleton对象时进行同步。另外考虑到public static SomeObject getInstance()可能是调用最频繁的,所以可以不加锁,只在创建方法上加锁。于是Singleton模式在多线程方式下,应当这样写:

public static synchronized SomeObject createInstance()
{
    if (instance == null)
    instance = new SomeObject();
}

public static SomeObject getInstance()
{
    if (instance == null)
    createInstance();
    return instance;
}

这样在createInstance()不会被创建多个对象。:)希望大家都很幸运,不会像我这样碰上这种让人郁闷的错误。

4,095 次阅读

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注