单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。
所有类都有构造方法,不编码则系统默认生成空的构造方法,若有显示定义的构造方法,默认的构造方法就会失效。于是,只要将类的构造方法写成是private的,那么外部程序就不能用new来实例化它了。
让类自身负责保存它的唯一实例,这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
多线程时的单例,双重锁定:
首先需要解释一下synchronized语句的含义,synchronized是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
懒汉式 Singleton类
package singleton; /** * 单例模式:饿汉模式 * 类一加载就实例化对象,提前占用系统资源 * @author 煞笔 * */ public class SingletonHungry { /** * 当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间, 从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例), 当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存 */ private static final SingletonHungry instance = new SingletonHungry(); // 定义一个私有构造方法 private SingletonHungry(){}; public static SingletonHungry getInstance() { return instance; } }
:
package singleton; /** * 单例模式:懒汉模式 * 线程安全 并且效率高 * @author 煞笔 * */ public class Singleton { //定义一个静态私有变量(不初始化,不使用final关键字,使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用) private static volatile Singleton instance; // 定义一个私有构造方法 private Singleton(){}; //定义一个共有的静态方法,返回该类型实例 public static Singleton getInstance(){ // 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率) if(instance==null){ //同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建) synchronized(Singleton.class){ if(instance==null){ //未初始化,则初始instance变量 //初始化static的instance,静态变量被创建并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存 instance = new Singleton(); } } } return instance; } }
饿汉式 SingletonHungry类