单例模式在多线程下的问题
单例设计模式有两种形式:一种是饥饿式
Java代码
package net.chopsuey.singleton;
public final class EagerSingleton
{
private static EagerSingleton singObj = new EagerSingleton();
private EagerSingleton()
{
}
public static EagerSingleton getSingleInstance()
{
return singObj;
}
}
package net.chopsuey.singleton;
public final class EagerSingleton
{
private static EagerSingleton singObj = new EagerSingleton();
private EagerSingleton()
{
}
public static EagerSingleton getSingleInstance()
{
return singObj;
}
}
比较明显,这种是线程安全的。因为static变量是在类被加载时(有可能没被实例化)初始化并仅被初始化一次。因为这样就可以保证只有一个singObj被初始化。
另外一种则是懒汉式
Java代码
package net.chopsuey.singleton;
public final class LazySingleton
{
private static LazySingleton singObj = null;
private LazySingleton()
{
}
public static LazySingleton getSingleInstance()
{
if (singObj == null)
{
singObj = new LazySingleton();
}
return singObj;
}
package net.chopsuey.singleton;
public final class LazySingleton
{
private static LazySingleton singObj = null;
private LazySingleton()
{
}
public static LazySingleton getSingleInstance()
{
if (singObj == null)
{
singObj = new LazySingleton();
}
return singObj;
}
这种则是线程不安全的了。因为当有多个线程一起调用getSingleInstance()时则可能会生成多个实例。因此才需要修改一下。修改为我之前的那段代码
Java代码
package net.chopsuey.singleton;
public class Singleton
{
private static class SingletonHolder
{
static Singleton instance = new Singleton();
}
public static Singleton getInstance()
{
return SingletonHolder.instance;
}
}
package net.chopsuey.singleton;
public class Singleton
{
private static class SingletonHolder
{
static Singleton instance = new Singleton();
}
public static Singleton getInstance()
{
return SingletonHolder.instance;
}
}
一个静态内部类内的一个静态成员就可以保证它只在类被加载时只初始化一次。因此不管有多少个线程来调用它,都只能得到同个实例(类被加载时初始化的那个)。