单例模式:确保每个类只有一个实例,并提供全局访问点来访问这个唯一实例。(Logging,driver objects)
实现:(1) 私有构造函数限制其他类的实例化
(2) 私有静态指向自身的成员变量,类唯一的实例
(3) 公有静态的方法,提供全局访问点来访问这个唯一实例
A.饿汉式单例:在类加载时就创建实例对象,优点无需考虑多线程同时访问的问题,缺点类加载慢,客户端不需要实用对象是也创建了实例,资源利用率不高。
public class Singleton2 { /* * 饿汉单例模式:在类加载的时候就创建一个单例模式. */ // 1.私有的构造函数,确保不能在类的外部访问该类的构造函数 private Singleton2(){ System.out.println("构造函数执行了"); } // 2.私有的唯一的静态实例变量,在类加载的时候就创建好单例对象 private final static Singleton2 instance = new Singleton2(); // 3.公开的静态工厂返回此类的唯一实例 public static Singleton2 getInstance(){ return instance; } }
B.懒汉式单例:在第一次(调用静态工厂方法)调用时将自己实例化,实现了延迟加载,必须处理好多线程同时访问。
public class Singleton { /* * 单例模式:单个实例服务于整个应用 * 懒汉式单例:只有在第一次请求实例的时候创建,并且只在第一次创建后,以后不再创建该类的实例 */ // 1.一个私有的指向自己的静态变量 private static Singleton instance; // 2.私有的构造方法,保证不能从外部创建对象 private Singleton(){} // 3.公开的静态工厂方法,返回该类的唯一实例(当发现没有实例没有初始化的时候才初始化) public static synchronized Singleton getInstance(){ //synchronized关键字保证线程安全性 if(instance == null){ instance = new Singleton(); System.out.println("创建Singleton类的实例"); }else { System.out.println("实例已经创建,不能再创建"); } return instance; } }
双重检查加锁机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了
多次在同步情况下进行判断所浪费的时间。
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; } }
原文:http://my.oschina.net/elain/blog/382590