单例模式——懒汉模式,饿汉模式
所谓单例模式,就是保证类在内存中只有一个对象
如何保证类在内存中只有一个对象?
我们平时在实例化对象时,基本都是通过new的方式来实例化一个对象,其实说白了就是调用了需要实例化类的默认的构造方法,所以为了保证类只有一个对象,我们需要将类的对象设置为private
1)控制类的创建,不让其他类创建本类的对象,即需要设置private属性
2)在本类中定义一个本类的对象
单例模式的用途:
单例模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。
单例模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。如果我们能够保证系统中自始至终只有唯一一个数据库连接对象,显然我们会节省很多内存开销和CPU利用率。这就是单例模式的用途。单例模式的适用性有如下描述:
1.当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2.当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
下面对单例模式的懒汉式和饿汉式进行简单介绍:
1.饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建
2.懒汉式:当程序第一次访问单件模式实例时才进行创建。
如何选择:如果单件模式实例在系统中经常被用到,饿汉式是一个不错的选择,反之,如果单件模式在系统中很少用到或者几乎不会用到时,那么懒汉式更好些。
饿汉模式demo(静态常量):
public class Singleton(){
private static Singleton ston=new Singleton();
private Singleton(){
}
public static Singleton getSingle(){
return ston;
}
}
优点:写法简单,在类装载的时候就完成了实例化。避免了线程同步的问题。
缺点:在类装载的时候就完成了实例化,没有达到LazyLoading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
懒汉式demo(双重检查):
public class Singleton{
private static volatile Singleton s = null;
private Singleton() { }
public static Singleton getSingle(){
if(s==null){
synchronized(Singleton.class){
if(s==null){
s = new Singleton();
}
}
}
return s;
}
}
Double-Check概念对于线程开发者来说不会陌生,如代码中所示,我们进行两次if(s==null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if(s==null),直接return实例化对象。
优点:线程安全;延迟加载;效率较高。