问题分析:
首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了,比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,即在整个的打印过程中我只有一个打印程序的实例。
简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。
单例模式的定义:
确保某一个类有且只有一个实例,而且自行实例化并向整个系统提供整个实例
单例模式的使用场景:
确保某个类有且只有一个对象的场景,避免产生多个对象那个消耗过多的资源,或者某种对象类型的对象只有应该有且只有一个。
实现单例模式的关键点:
1,构造函数不对外开放,一般为Private
2,通过一个静态方法或者枚举返回单例类对象
3,确保单例类的对象有且只有一个,尤其是在多线程环境下
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
简单点呢就是:
首先,单例模式使类在程序生命周期的任何时刻都只有一个实例,
然后,单例的构造函数是私有的,外部程序如果想要访问这个单例类的话,
必须通过 GetInstance()来请求(注意是请求)得到这个单例类的实例。
懒汉模式:
public class Singleton {
private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
private static Singleton mSingleton=null;//私有静态常量没有实例化:private保证只能内部访问该变量,static与类有关
public static synchronized Singleton getSingleton(){//公有静态放法:加了一个同步
if(mSingleton=null)
{
mSingl eton=new Singleton();
}
return mSingleton;
}
何为懒汉式单例呢,可以这样理解,单例模式呢,其在整个应用程序的生命周期中只存在一个实例,懒汉式呢,就是这个单例类的这个唯一实例是在第一次使用 getSingleton()时实例化的,如果您不调用 getSingleton()的话,这个实例是不会存在的,即为 null。形象点说,就是你不去动它的话,它自己是不会实例化的,所以可以称之为懒汉
首先这个 Singleton 类会在在第一次调用 getSingleton()时创建一个实例,并将这个实例的引用封装在自身类中,然后以后调用 getSingleton()时就会判断这个 Singleton 是否存在一个实例了,如果存在,则不会再创建实例。而是调用以前生成的类的实例,这样下来,整个应用程序中便就只存在一个实例了。
优点:每次只在使用时被实例化,
缺点:每次调用getSingleton()都要进行同步,造成不必要的同步开销,不建议使用
饿汉模式:
public class Singleton {
private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
private static final Singleton mSingleton=new Singleton();//私有静态常量并实例化:private保证只能内部访问该变量,static与类有关,final一旦初始化就不能修改
public static Singleton getSingleton(){//公有静态放法:只能通过此方法来获取静态常量
return mSingleton;
}
上面介绍了饿汉式单例,到这里来理解懒汉式单例的话,就容易多了,懒汉式单例由于人懒,所以其自己是不会主动实例化单例类的唯一实例的,而饿汉式的话,则刚好相反,其由于肚子饿了,所以到处找东西吃,人也变得主动了很多,所以根本就不需要别人来催他实例化单例类的为一实例,其自己就会主动实例化单例类的这个唯一类。
例子:一个公司只有一个CEO,可以有几个VP,无数个员工,但CEO只有一个
Staff.java
public class Staff{
public void work(){
//干活
}
}
VP.java
public class VP extends Staff {
@Override
public void work(){
//管理员工
}
}
CEO.java
package com.hust.singleton;
//CEO 单例模式(饿汉模式)
public class CEO extends Staff{
private CEO(){};//私有构造函数:使外部不能使用构造函数来创建该对象
private static final CEO mCEO=new CEO();//私有静态常量并实例化:private保证只能内部访问该变量,static与类有关,final一旦初始化就不能修改
public static CEO getCEO(){//公有静态放法:只能通过此方法来获取静态常量
return mCEO;
}
@Override
public void work(){
//管理VP
}
}
/*1.饿汉模式
* public class Singleton {
private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
private static final Singleton mSingleton=new Singleton();//私有静态常量并实例化:private保证只能内部访问该变量,static与类有关,final一旦初始化就不能修改
public static Singleton getSingleton(){//公有静态放法:只能通过此方法来获取静态常量
return mSingleton;
}
* 2,懒汉模式,优点:每次只在使用时被实例化,缺点:每次调用getSingleton()都要进行听不,造成不必要的同步开销,不建议使用
* public class Singleton {
private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
private static Singleton mSingleton=null;//私有静态常量没有实例化:private保证只能内部访问该变量,static与类有关
public static synchronized Singleton getSingleton(){//公有静态放法:加了一个同步
if(mSingleton=null)
{
mSingl eton=new Singleton();
}
return mSingleton;
}
*
*
*
*/
Company.java
package com.hust.singleton;
import java.util.ArrayList;
import java.util.List;
public class Company {
private List<Staff> mAllStaffs=new ArrayList<Staff>();
public void addStaff(Staff mStaff) {
mAllStaffs.add(mStaff);
}
public void showAllStaffs() {
for(Staff mStaff:mAllStaffs){
System.out.println("Obj:"+mStaff.toString());
}
}
}
Test.java
package com.hust.singleton;
import java.security.PublicKey;
public class TestSingleton {
/**
* @param args
*/
public static void main(String[] args) {
Company mCompany=new Company();
//CEO对象只能通过getCEO函数获取
Staff mCeo1=CEO.getCEO();
Staff mCeo2=CEO.getCEO();
mCompany.addStaff(mCeo1);
mCompany.addStaff(mCeo2);
//通过new创建VP对象
Staff mVP1=new VP();
Staff mVP2=new VP();
mCompany.addStaff(mVP1);
mCompany.addStaff(mVP2);
//通过new创建Staff对象
Staff mStaff1=new Staff();
Staff mStaff2=new Staff();
Staff mStaff3=new Staff();
mCompany.addStaff(mStaff1);
mCompany.addStaff(mStaff2);
mCompany.addStaff(mStaff3);
mCompany.showAllStaffs();
}
}
输出结果:
Obj:com.hust.singleton.CEO@15db9742
Obj:com.hust.singleton.CEO@15db9742//只有一个实例
Obj:com.hust.singleton.VP@6d06d69c
Obj:com.hust.singleton.VP@7852e922
Obj:com.hust.singleton.Staff@4e25154f
Obj:com.hust.singleton.Staff@70dea4e
Obj:com.hust.singleton.Staff@5c647e05