饿汉模式:
public class Singleton1 {
private static Singleton1 singleton = new Singleton1();
private Singleton1(){
}
public static Singleton1 getInstance(){
return singleton;
}
}
这个会在Singleton1 类在加载时就创建实例对象。如果是配置类(数量较少的)还可以接受,如果是大量的单例都用这种写法就会有不必要的系统资源浪费,很多被创建出来的实例有可能并没有被使用到。
饱汉模式:
public class Singleton2 {
private static Singleton2 singleton;
private Singleton2(){
}
public static synchronized Singleton2 getInstance(){
if(singleton == null)
singleton = new Singleton2();
return singleton;
}
}
这个就不会。当需要用到该实例对象时才会去加载该实例,但是存在线程安全的问题。所以优化版的饱汉模式:
public
class
SynchronizedSingleton {
//一个静态的实例
private
static
SynchronizedSingleton synchronizedSingleton;
//私有化构造函数
private
SynchronizedSingleton(){}
//给出一个公共的静态方法返回一个单一实例
public
static
SynchronizedSingleton getInstance(){
if
(synchronizedSingleton ==
null
) {
synchronized
(SynchronizedSingleton.
class
) {
if
(synchronizedSingleton ==
null
) {
synchronizedSingleton =
new
SynchronizedSingleton(); }
}
}
return
synchronizedSingleton;
}
}
这种写法也被称为双重锁机制。一般教科书上的范本也是这样。但是这种情况如果深入,在考虑JVM的情况下也会有并发的问题。出现这种问题主要由于jvn的指令重排机制,在new对象的过程中会出现并发的问题,可以加上volatile关键字再度优化一下
public class SynchronizedSingleton {
//一个静态的实例
private volatile static SynchronizedSingleton synchronizedSingleton;
//私有化构造函数
private SynchronizedSingleton(){}
//给出一个公共的静态方法返回一个单一实例
public static SynchronizedSingleton getInstance(){
if (synchronizedSingleton == null) {
synchronized (SynchronizedSingleton.class) {
if (synchronizedSingleton == null) {
synchronizedSingleton = new SynchronizedSingleton(); }
}
} return synchronizedSingleton;
}
}
还有一种内部类的写法机制也值得推荐:
public
class
Singleton {
private
Singleton(){}
public
static
Singleton getInstance(){
return
SingletonInnerInstance.instance;
}
private
static
class
SingletonInnerInstance{
static
Singleton instance =
new
Singleton();
}
}