java-設計模式-單例模式
單例模式
一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
一个类只有一个实例,且该类能自行创建这个实例的一种模式。
簡單的對比就是:
例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,
或出现各个窗口显示内容的不一致等错误。
特點
单例类只有一个实例对象;
该单例对象必须由单例类自行创建;
单例类对外提供一个访问该单例的全局访问点。
應用場景
需要频繁创建的一些类,使用单例可以降低系统的内存压力,减少 GC。
某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。
某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
频繁访问数据库或文件的对象。
对于一些控制硬件级别的操作,或者从系统上来讲应当是单一控制逻辑的操作,如果有多个实例,则系统会完全乱套。
当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。
如 Web 中的配置对象、数据库的连接池等
實現步驟:
在类中添加一个私有静态成员变量用于保存单例实例。 声明一个公有静态构建方法用于获取单例实例。 在静态方法中实现"延迟初始化"。 该方法会在首次被调用时创建一个新对象, 并将其存储在静态成员变量中。
此后该方法每次被调用时都返回该实例。 将类的构造函数设为私有。 类的静态方法仍能调用构造函数, 但是其他对象不能调用。 检查客户端代码, 将对单例的构造函数的调用替换为对其静态构建方法的调用。
懶漢式的單例模式
/** * 懶漢式單例設計模式 * * 特點;'类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例 * */ public class LaziSingleton { //volatile,若变量发生变化,这同步到所有的线程中。 private static volatile LaziSingleton instance =null; //私有有構造函數 private LaziSingleton(){} public static synchronized LaziSingleton getInstance(){ if (instance == null){//如果對象還沒有被創建,那就新建一個實列 instance = new LaziSingleton(); } return instance; } /** * 编写的是多线程程序,则不要删除上例代码中的关键字 volatile * 和 synchronized,否则将存在线程非安全的问题。 */ }
餓漢式的單例模式
/** * 餓漢式單例 * * 特點:类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了 */ public class HungrySingleton { //加載的時候就創建實列 private static final HungrySingleton instance = new HungrySingleton(); private HungrySingleton(){} private static HungrySingleton getInstance(){ return instance; } /** * 在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变, * 所以是线程安全的,可以直接用于多线程而不会出现问题。 */ }
簡單實踐驗證
建立一個單例模型的類:
/** * 单例模式 */ public class President { //volatile,若变量发生变化,这同步到所有的线程中。 private static volatile President instance = null; /** * 私有化构造函数,避免使用new创建的实例 */ private President(){ System.out.println("new a President"); } /** * synchronized关键字作用:保证方法或者代码在运行时,得到锁。 * 统一时刻只有一个方法执行。保证共享变量内存可见性 * 可见性 * @return */ //运行该方法的时候只有一个线程能够得到锁。避免出现创建两个实例的情况 public static synchronized President getInstance() { if (instance == null){ instance = new President(); }else { System.out.println("exist a President"); } return instance; } // public void something(){ System.out.println("president--end"); } }
測試代碼:
’
public class SingletonTest { public static void main(String[] args) { President president1 = President.getInstance(); President president2 = President.getInstance(); president1.something(); president2.something(); /** * 判断是否为同一实例 */ if (president1 == president2){ System.out.println("president1 == president2"); }else { System.out.println("president1 != president2"); } } /** new a President exist a President president--end president--end president1 == president2 */ }