什么是单例模式?
单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点:
- 一个类只能有一个实例;
- 自己创建这个实例;
- 整个系统都要使用这个实例。
如何实现单例模式?
单例设计模式有两种表现形式:
- “饿汉式”
- “懒汉式”
public class Single
{
private Single(){}//构造方法私有化
private static Single instance = new Single();//实例化对象
public static Single getInstance()
{
return instance;//暴露方法返回instance的对象
}
}
饿汉式的特点:创建对象的同时就直接实例化对象。
那我们在看看“懒汉式”:
public class Single
{
private Single(){}//构造方法私有化
private static Single instance = null;
public static Single getInstance()
{
if (instance==null)//这里判断看instance是否为空
{
instance = new Single();//对象为空,实例化对象
}
return instance;//返回对象
}
}
懒汉式的特点:方法被加载时才进行初始化操作,“懒汉式”又被称为延迟加载设计模式。
仔细观察,懒汉式的代码是有弊端的,我们来看看。
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{ // 锁是谁?字节码文件对象;
if (s == null)//该处判断是减少判断,增加效率
{
synchronized (Single.class)//保证线程安全
{
if (s == null)//判断对象是否为空
s = new Single();//实例化对象
}
}
return s;//返回变量
}
}
当多线程访问懒汉式时,因为懒汉式的方法内对共性数据进行多条语句的操作。所以容易出现线程安全问题。
上面加了几处判断,我们来分析下:
- s==null 是为了减少判断,增加效率
- synchronized (Single.class)为了保证线程安全
- if (s == null)是为了判断对象是否为空
为了解决,加入同步机制,解决安全问题。但是却带来了效率降低。所以我们不建议使用“懒汉式”,饿汉式简单高效,安全。
单例模式的用在哪儿?
- 网站的计数器,一般也是采用单例模式实现,否则难以同步。
- 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
- Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
- 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
- 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
- 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
好了,到这里,我们的单例设计模式也基本接近尾声了,发现对于单例的解读也不是非常难,本身设计模式的目的就是为了方便编程才有了它的用武之地,所以设计模式掌握了其本质,也不会有那种“高大上”的阴影啦,好了,我们继续加油吧!