什么是单例模式?
单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。
Why Singleton pattern
/** * 一、懒汉,常用的写法 */ class LazySingleton{ private static LazySingleton singleton; private LazySingleton(){ } public static LazySingleton getInstance(){ if(singleton==null){ singleton=new LazySingleton(); } return singleton; } }
class HungrySingleton{ private static HungrySingleton singleton=new HungrySingleton(); private HungrySingleton(){} public static HungrySingleton getInstance(){ return singleton; } }
/** * 三、静态内部类 优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading */ class InternalSingleton{ private static class SingletonHolder{ private final static InternalSingleton INSTANCE=new InternalSingleton(); } private InternalSingleton(){} public static InternalSingleton getInstance(){ return SingletonHolder.INSTANCE; } }
1、 自由序列化;
2、 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);
3、 线程安全;
public enum AnimalHelperSingleton { INSTANCE; private AnimalHelperSingleton(){ } public Animal[] buildAnimalList(){ final Animal[] animals = new Animal[10]; animals[0] = new SimpleAnimal(Animal.AnimalClass.MAMMAL, "Dog", true, Color.GRAY); animals[1] = new SimpleAnimal(Animal.AnimalClass.MAMMAL, "Cat", true, Color.YELLOW); animals[2] = new SimpleAnimal(Animal.AnimalClass.AMPHIBIAN, "Frog", true, Color.GREEN); animals[3] = new SimpleAnimal(Animal.AnimalClass.BIRD, "Crow", true, Color.BLACK); animals[4] = new SimpleAnimal(Animal.AnimalClass.BIRD, "Cardinal", true, Color.RED); animals[5] = new SimpleAnimal(Animal.AnimalClass.ARTHROPOD, "Mantis", false, Color.GREEN); animals[6] = new SimpleAnimal(Animal.AnimalClass.ARTHROPOD, "Spider", false, Color.ORANGE); animals[7] = new SimpleAnimal(Animal.AnimalClass.MAMMAL, "Tiger", true, Color.ORANGE); animals[8] = new SimpleAnimal(Animal.AnimalClass.MAMMAL, "Bear", true, Color.BLACK); animals[9] = new SimpleAnimal(Animal.AnimalClass.BIRD, "Owl", true, Color.BLACK); return animals; } }
//Call singleton to build the animal list. Animal[] animals = AnimalHelperSingleton.INSTANCE.buildAnimalList();
<span style="color:#008200;"> </span>public class Singleton{ private static Singleton instance = null;//是否是final的不重要,因为最多只可能实例化一次。 private Singleton(){} public static Singleton getInstance(){ if(instance == null){ //双重检查加锁,只有在第一次实例化时,才启用同步机制,提高了性能。 synchronized(Singleton.Class){ if(instance == null){ instance = new Singleton(); } } } return instance; } }<span style="color:#008200;"> </span>
连接阶段:这个阶段分为三个步骤,
步骤一:验证,验证什么呢?当然是验证这个class文件里面的二进制数据是否符合java规范咯;
步骤二:准备,为该类的静态变量分配内存空间,并将变量赋一个默认值,比如int的默认值为0;
步骤三:解析,这个阶段就不好解释了,将符号引用转化为直接引用,涉及到指针,这里不做多的解释;
初始化阶段:当我们主动调用该类的时候,将该类的变量赋于正确的值(这里不要和第二阶段的准备混淆了),举个例子说明下两个区别,比如一个类里有private static int i = 5; 这个静态变量在"准备"阶段会被分配一个内存空间并且被赋予一个默认值0,当道到初始化阶段的时候会将这个变量赋予正确的值即5,了解了吧!