单例模式(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模式则强制行为上的单一性,而没有强加结构方面的限制

原文地址:https://www.cnblogs.com/budoudou/p/2299821.html