单例模式 只在一个程序里只能有一个实例
什么情况下要用单例模式呢?
举个例子:有一块大蛋糕cake类 100口可以吃完他
每次有人过来都要拿起蛋糕吃一口,这时候我们就希望拿的是同一个蛋糕,这样100个人就可以吃完了。
如果每个人拿的蛋糕都是新的,那就不符合我们的目的了。
package test.design.singleTan;
public class people {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这是一个最简单的people类,只有两个属性,
正常我们调用它
package test.design.singleTan;
public class test {
public static void main(String[] args) {
People people1=new People();
People people2=new People();
System.out.println(people1==people2);
}
}
输出false,很显然这是两个实例
那么我们怎么写成单例模式呢?
实现一:饿汉模式
1.把构造方法私有化
2.定义一个静态变量
3.提供一个返回静态变量的方法
package test.design.singleTan;
public class People {
private static People people=new People();
private int age;
private String name;
private People(){}
public static People getPeople(){
return people;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
我们调用
package test.design.singleTan;
/**
* Created by Administrator on 2018/8/7.
*/
public class test {
public static void main(String[] args) {
People people1=People.getPeople();
People people2=People.getPeople();
System.out.println(people1==people2);
}
}
返回true;说明两个调用的是一个实例。
但是饿汉模式是有缺点的,他是不管你吃不吃蛋糕,都会做出一个蛋糕出来。
如果你不吃的东西很多,苹果,香蕉,栗子。这些都要占用空间,那CPU就要爆了。
所以就需要另一种实现。
实现二:懒汉模式
我们需要设计一个只有用它才new一个实例,不用就不new的类
package test.design.singleTan;
public class People {
private static People people;
private int age;
private String name;
private People(){}
public static People getPeople(){
if(people==null){
people=new People();
}
return people;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
首先静态变量people是没有值的,
这里只在getPeople方法里面加了一个判断,如果没有值就new一个,如果有值则直接返回。
这样就达到了 你不调用我,我不会new一个实例,即没人吃蛋糕,我就不做,有人想吃蛋糕我才会做一个出来,
当后来人想吃蛋糕时,直接吃我之前做的那个就好了。
但是这个方法也有个问题,在多个进程调用的时候,可能会new多个实例出来。
所以,要解决多线程问题。
public class People {
private static People people;
private int age;
private String name;
private People(){}
public static People getPeople(){
if(people==null){
synchronized (people){
if (people==null){
people=new People();
}
}
}
return people;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这里加上了同步代码块,保证多线程条件下只new出一个实例。