zoukankan      html  css  js  c++  java
  • 单例模式(Singleton Pattern & MonoState)

    确保一个类只有一个实例并提供一个对它的全局访问指针

    public class Person {
    private String name;
    private int age;
    private static Person person;

    protected Person() {
    super();
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    public static Person getInstance() {
    return person==null?new Person():person;
    }

    public void eat() {
    DebugLog.log("i am eating");
    }

    public void play() {
    DebugLog.log("i am playing");
    }
    }

    1. 该singleintance会有二个问题:

    a:构造函数声明为protected,导致同包下面的的class都可以contruct该class,在内存中有可能存在二份实例

    b:如果二个线程同时getinstance,也可能使内存中存在二份实例

    public class Person {
    private String name;
    private int age;
    private static Person person;

    private Person() {
    super();
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    public static synchronized Person getInstance() {
    return person==null?new Person():person;
    }

    public void eat() {
    DebugLog.log("i am eating");
    }

    public void play() {
    DebugLog.log("i am playing");
    }

    public static Person ModifiedgetInstance() {
    if (person == null) {
    synchronized (Person.class) {
    person = new Person();
    }
    }
    return person;
    }
    }

    先看getInstance这个方法,他将该方法都sync住了,其实完全没有必要锁住整个方法,试想下如果getInstance这个方法很长很大,

    是不是太浪费时间了,所以出现了ModifiedgetInstance这个修正的方法,在new 之前将资源锁住就可以了。

    其实还有更好的方法,因为sync比较耗时,导致系统变慢,完全可以考虑下面比较优雅的方法:

    public class Person {
    private String name;
    private int age;
    private final static Person person = new Person();

    private Person() {
    super();
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    public static Person getInstance() {
    return person;
    }

    public void eat() {
    DebugLog.log("i am eating");
    }

    public void play() {
    DebugLog.log("i am playing");
    }
    }

    这样既不会有性能问题,也不会出现二个instance 实例。

    下面monostate粉末登场了:

    public class Person {
    private String name;
    private static int age;

    public Person() {
    super();
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }


    public void eat() {
    DebugLog.log("i am eating");
    }

    public void play() {
    DebugLog.log("i am playing");
    }

    }

    可以看出即使有多个instance实例,也能保证age的唯一性:

    二者比较下:

    SINGLETON模式强制结构上的单一性,它防止创建出多个对象实例

    MONOSTATE模式则强制行为上的单一性,而没有强加结构方面的限制

  • 相关阅读:
    VS2005服务器资源管理器的bug ?
    今天新开张 ^_^
    SharePoint更改当前登录用户密码的WebPart
    开启SharePoint页面的Session功能
    创建强命名程序集的WebPart
    操作SSO对象模型时,异常“SSO_E_CANARY_VALIDATION_FAILURE”的处理
    关于页面加载时比较常用的几个公共事件
    活动目录概述
    SharePoint中利用客户端脚本获得当前登录用户信息
    SharePoint文档库中上下文菜单的菜单项
  • 原文地址:https://www.cnblogs.com/budoudou/p/2299821.html
Copyright © 2011-2022 走看看