1.单例模式使用的目的:是为了尽可能的节约内存空间,减少无谓的GC消耗,并且使应用可以正常运作。
2. 单例特征:这些类,在应用中如果有两个或者两个以上的实例会引起错误,或者说,这些类在整个应用中,同一时刻,有且只能有一种状态。
3.单例模式示例:
1.最原始的单例模式的构造方式(不考虑并发访问的情况下标准的单例模式的构造方式)
public class Singleton {
//一个静态的实例
private static Singleton singleton;
//私有化构造函数
private Singleton(){}
//给出一个公共的静态方法返回一个单一实例
public static Singleton getInstance(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
2.粗暴的處理并發的方式
public class BadSynchronizedSingleton {
//一个静态的实例
private static BadSynchronizedSingleton synchronizedSingleton;
//私有化构造函数
private BadSynchronizedSingleton(){}
//给出一个公共的静态方法返回一个单一实例
public synchronized static BadSynchronizedSingleton getInstance(){
if (synchronizedSingleton == null) {
synchronizedSingleton = new BadSynchronizedSingleton();
}
return synchronizedSingleton;
}
}
弊端:将整个获取实例的方法同步,这样在一个线程访问这个方法时,其它所有的线程都要处于挂起等待状态,避免了刚才同步访问创造出多个实例的危险,但是这样会造成很多无谓的等待。
3.我们同步的地方只是需要发生在实例还未创建的时候,在实例创建以后,获取实例的方法就没必要再进行同步控制了,称为双重加锁。
1 public class SynchronizedSingleton { 2 3 //一个静态的实例 4 private static SynchronizedSingleton synchronizedSingleton; 5 //私有化构造函数 6 private SynchronizedSingleton(){} 7 //给出一个公共的静态方法返回一个单一实例 8 public static SynchronizedSingleton getInstance(){ 9 if (synchronizedSingleton == null) { 10 synchronized (SynchronizedSingleton.class) { 11 if (synchronizedSingleton == null) { 12 synchronizedSingleton = new SynchronizedSingleton(); 13 } 14 } 15 } 16 return synchronizedSingleton; 17 } 18 }
如果深入到JVM中去探索上面这段代码,它有可能是有问题的。
4.标准单例模式
1 public class Singleton { 2 3 private Singleton(){} 4 5 public static Singleton getInstance(){ 6 return SingletonInstance.instance; 7 } 8 9 private static class SingletonInstance{ 10 static Singleton instance = new Singleton(); 11 12 } 13 }
5.饿汉式单例模式
1 public class Singleton { 2 3 private Singleton(){}; 4 private static Singleton singleton = new Singleton(); 5 public static Singleton getInstance(){ 6 return singleton; 7 } 8 }
6.饱汉式单例模式
1 public class SingletonDemo { 2 private static volatile SingletonDemo instance = null; 3 private SingletonDemo(){ } 4 public static SingletonDemo getInstance(){ 5 if(instance==null){ 6 synchronized(SingletonDemo.class){ 7 if(instance==null){ 8 instance = new SingletonDemo(); 9 } 10 } 11 } 12 return instance; 13 } 14 } 15 }