Java攻城狮的入门课程Java学习笔记程序员

单例设计模式

2017-03-24  本文已影响69人  黒猫

该模式可以保证一个类只能有一个实例

Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍:懒汉式单例、饿汉式单例。
  
  单例模式有以下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

对于系统中的某些类来说,只有一个实例很重要,例如:一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器,如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态;与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

饿汉式:
类一旦加载,就把对象初始化完成,保证使用 getInstance()方法时,对象已经存在。

class Single {
    /*
     * 默认情况下 
     * 一个类可以有多个对象 
     * 如果要使single类只能有一个对象 
     * 首先要保证不可以使用new来创建多个对象
     * 使用new来创建对象,实际上是使用构造函数 
     * 因此将构造函数用private修饰即可
     */
    private Single() {
    }
    /*
     * 但此时出现的问题是外部一个对象也无法创建 
     * 单例设计模式还要求有一个对象 
     * 因此在外部无法创建对象的情况下 
     * 只有在类的内部创建一个single类型的对象
     * 相当于single类内部的一个成员变量 
     * 为了使外部能得到该对象 
     * 将其修饰为static 
     * 同时为了避免外部其设为null
     * 从而出现得不到对象的情况 
     * 还需要将该对象也设为私有
     */
    private static Single s = new Single();
    /*
     * 但为了使外部可以获得该对象 
     * 使用公有的方法将对象提供出去 
     * 此时就保证了single类只有一个实例
     */
    public static Single getInstance() {
        return s;
    }
}

public class Test {

    public static void main(String[] args) {
        /*
         * 创建两个对象s1、s2
         * 如果是同一个对象
         * 那么内存地址也相同
         * 输出的结果应为true
         */
        Single s1 = Single.getInstance();
        Single s2 = Single.getInstance();
        System.out.println(s1==s2);
        // 结果为true
    }
}

懒汉式:
只有当调用 getInstance()方法时,才返回去初始化对象。

class Single {
    private Single() {
    }
    /*
     * 与饿汉式不同
     * 懒汉式在此处仅仅定义一下Single对象
     * 并不创建对象
     */
    private static Single s;
    /*
     * 此处添加判断
     * 当外部首次调用公有方法时
     * 判断Single对象是否为空
     * 为空就创建对象并返回
     * 当再次调用该方法时
     * 判断Single对象不为空
     * 因此不创建对象
     * 依然返回上次创建的对象
     * 实现了single类只有一个实例
     */
    public static Single getInstance() {
        if(s==null){
            s = new Single();
        }
        return s;
    }
}

public class Test {

    public static void main(String[] args) {
        /*
         * 创建两个对象s1、s2
         * 如果是同一个对象
         * 那么内存地址也相同
         * 输出的结果应为true
         */
        Single s1 = Single.getInstance();
        Single s2 = Single.getInstance();
        System.out.println(s1==s2);
        // 结果为true
    }
}

注意:
通常使用饿汉式,因为懒汉式在多线程程序中存在有安全问题,详细内容请看synchronized详解中的第6部分。


版权声明:欢迎转载,欢迎扩散,但转载时请标明作者以及原文出处,谢谢合作!             ↓↓↓
上一篇下一篇

猜你喜欢

热点阅读