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