单例模式:保证系统中一个类只有一个实例。即一个类只有一个对象实例
如何实现:
一是单例模式的类只提供私有的构造函数,
二是类定义中含有一个该类的静态私有对象,
三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
以下是具体示例:
1、假设有一个企业名为HeadFirstPizzaEnterprise,因为整个程序中只允许有一个HeadFirstPizzaEnterprise的对象,所以应用单例模式。
/*
* HeadFirstPizza企业
* 旗下有很多pizza店
* 使用观察者模式、单例模式
*/
public class HeadFirstPizzaEnterprise extends Enterprise{
//二:类定义中含有一个该类的静态私有对象
private static HeadFirstPizzaEnterprise headFirstPizzaEnterprise;
//一:单例模式的类只提供私有的构造函数
private HeadFirstPizzaEnterprise() {
super("HeadFirstPizza集团有限公司");
this.pizzaStores = new HashMap<>();
System.out.println("Congratulations, 今天,我们成立了"+name);
}
//三:该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
public static HeadFirstPizzaEnterprise getInstance() {
if (headFirstPizzaEnterprise == null){
headFirstPizzaEnterprise = new HeadFirstPizzaEnterprise();
}
return headFirstPizzaEnterprise;
}
//根据区域搜索公司旗下的披萨店
public PizzaStore getStore(String location) {
PizzaStore pizzaStore = null;
if (pizzaStores.containsKey(location)){
pizzaStore = pizzaStores.get(location);
}else{
pizzaStore = null;
}
return pizzaStore;
}
}
2、写个测试类实验一下
/*
* 实现runna接口,模拟多线程调度
*/
public class UseHeadFirstPizzaEnterprise implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
HeadFirstPizzaEnterprise headFirstPizzaEnterprise = HeadFirstPizzaEnterprise.getInstance();
}
}
/*
* 创建多个进程来获取单例
*/
public class SingletonPatternTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=0; i<100; i++){
System.out.println(i);
UseHeadFirstPizzaEnterprise useHeadFirstPizzaEnterprise = new UseHeadFirstPizzaEnterprise();
Thread thread = new Thread(useHeadFirstPizzaEnterprise);
thread.start();
}
}
}
3、运行结果如下,因为多线程没有做同步处理,导致存在创建多个对象的场景。
4、加入同步机制
单例模式在使用过程中有多种方法来实现同步机制,上述方法只是其中一种。
/*
* HeadFirstPizza企业
* 旗下有很多pizza店
* 使用观察者模式、单例模式
*/
public class HeadFirstPizzaEnterprise extends Enterprise{
//二:类定义中含有一个该类的静态私有对象
private static volatile HeadFirstPizzaEnterprise headFirstPizzaEnterprise;
//一:单例模式的类只提供私有的构造函数
private HeadFirstPizzaEnterprise() {
super("HeadFirstPizza集团有限公司");
this.pizzaStores = new HashMap<>();
System.out.println("Congratulations, 今天,我们成立了"+name);
}
//三:该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
public static HeadFirstPizzaEnterprise getInstance() {
if (headFirstPizzaEnterprise == null){
synchronized (HeadFirstPizzaEnterprise.class) {
if (headFirstPizzaEnterprise == null){
headFirstPizzaEnterprise = new HeadFirstPizzaEnterprise();
}
}
}
return headFirstPizzaEnterprise;
}
//根据区域搜索公司旗下的披萨店
public PizzaStore getStore(String location) {
PizzaStore pizzaStore = null;
if (pizzaStores.containsKey(location)){
pizzaStore = pizzaStores.get(location);
}else{
pizzaStore = null;
}
return pizzaStore;
}
}
5、再次测试,发现只调用了一次类构造函数,也就是说只创建了一个对象
ps:单例模式在使用过程中有多种方法来实现同步机制,上述方法只是其中一种。