单例模式的好处能够帮助我们实现对象只创建一个实例,并且提供一个全局的访问接口。在android开发中,单例模式能够很好的帮助我们减少对象的创建,从而提高应用的整体性能。在web程序中,单例模式常常应用在工具类等应用场合,例如jdbc连接工具类
初次接触单例模式,先看一个简单的demo:
public class SendService {
private static SendService sendService = null; //整个应用唯一的静态SendService对象,在类一加载的时候立即被创建,立即初始化保证每次都从内存中读取
private SendService(){ //私有化类SendService的构造方法,调用者不得私自调用
}
//向外界统一暴露一个接口,如果调用SendService的其他方法,必须调用此方法生成对象
public static SendService getInstence(){
if(sendService ==null ){
sendService = new SendService();
}
return sendService;
}
//其它方法,尽量避免申明为static,否则失去单例模式就失去了意义
public void otherFunction(){
//dosomething yourself;
}
}
以上简单demo经过简单测试会发现,在多线程中会发现问题。
可以将为getInstence方法加上一个synchronized 同步锁,但是这种情况下又影响了系能!
后来人家就在此基础上加工能为饿汉式和懒汉式两种单例模式
饿汉式:
/**
* 饿汉式
*/
public class SendService {
private static static SendService sendService = new SendService;
private SendService(){
}
public static SendService getInstance() {
return sendService;
}
}
饿汉式不会出现并发问题,在
ClassLoader
加载类后
实例就会第一时间被创建,饿汉式的创建方式在一些场景中将无法使用:当
实例的创建是依赖参数或者配置文件的,在
getInstance()
之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。
懒汉式:
/**
* 懒汉式
*/
public class SendService {
private static class SingletonHolder {
static final SendService sendService = new SendService();
}
public static SendService getInstance() {
return SingletonHolder.sendService;
}
}
懒汉式仍然使用JVM本身机制保证了线程安全问题;由于SingletonHolder是私有的,除了getInstance()之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖JDK版本。
第一个demo到第二个demo之间的原因讲的不是很清楚,待笔者在实际开发中有了更深的理解后再补充吧!